django-admin:创建、保存和关联 m2m 模型

发布于 2024-10-02 13:20:13 字数 551 浏览 4 评论 0原文

我有两个模型:

class Production(models.Model):
    gallery = models.ManyToManyField(Gallery)

class Gallery(models.Model):
    name = models.CharField()

我的作品管理员中有 m2m 关系,但我想要这样的功能:当我创建新作品时,会创建一个默认图库,并在两者之间注册关系。

到目前为止,我可以通过覆盖生产保存来创建默认图库:

def save(self, force_insert=False, force_update=False):
    if not ( Gallery.objects.filter(name__exact="foo").exists() ):
        g = Gallery(name="foo")
        g.save()
        self.gallery.add(g)

这将创建并保存模型实例(如果它尚不存在),但我不知道如何注册两者之间的关系?

I have two models:

class Production(models.Model):
    gallery = models.ManyToManyField(Gallery)

class Gallery(models.Model):
    name = models.CharField()

I have the m2m relationship in my productions admin, but I want that functionality that when I create a new Production, a default gallery is created and the relationship is registered between the two.

So far I can create the default gallery by overwriting the productions save:

def save(self, force_insert=False, force_update=False):
    if not ( Gallery.objects.filter(name__exact="foo").exists() ):
        g = Gallery(name="foo")
        g.save()
        self.gallery.add(g)

This creates and saves the model instance (if it doesn't already exist), but I don't know how to register the relationship between the two?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

后知后觉 2024-10-09 13:20:13

您可以通过在 Production 上调用 add 来注册关系。问题是您正在保存 Gallery,而不是您已覆盖其 saveProduction。您需要在 save 结束时调用 super(...).save(...)

def save(self, force_insert=False, force_update=False):
    if not ( Gallery.objects.filter(name__exact="foo").exists() ):
        g = Gallery(name="foo")
        g.save()
        self.gallery.add(g)
    super(Production, self).save(force_insert=force_insert, force_update=force_update)

此外,由于您在这里处理两个模型,你应该使用 Django 的信号,可能是 post -save,这也会给你created标志:

def create_default_gallery(sender, instance, created, **kwargs):
    if created and not Gallery.objects.filter(name__exact="foo").exists():
        g = Gallery(name="foo")
        g.save()
        instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)

尽管这仍然不会达到你所说的目的;如果您确实希望将默认 Gallery 与每个新的 Production 相关联,即使您没有创建默认 Gallery,您也需要这样做代码>:

def create_default_gallery(sender, instance, created, **kwargs):
    if created:
        g = Gallery.objects.get_or_create(name__exact="foo")
        g.save()
        instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)

You register the relationship just as you have, by calling add on the Production. The problem is that you're saving the Gallery, but not the Production whose save you've overridden. You need to call super(...).save(...) at the end of your save:

def save(self, force_insert=False, force_update=False):
    if not ( Gallery.objects.filter(name__exact="foo").exists() ):
        g = Gallery(name="foo")
        g.save()
        self.gallery.add(g)
    super(Production, self).save(force_insert=force_insert, force_update=force_update)

Furthermore, since you're dealing with two models here, you should use Django's signals for this, probably post-save, which will also give you the created flag:

def create_default_gallery(sender, instance, created, **kwargs):
    if created and not Gallery.objects.filter(name__exact="foo").exists():
        g = Gallery(name="foo")
        g.save()
        instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)

Though this still won't do what you say you want; if you really want to associate the default Gallery with every new Production, you'll want to do it even when you're not creating the default Gallery:

def create_default_gallery(sender, instance, created, **kwargs):
    if created:
        g = Gallery.objects.get_or_create(name__exact="foo")
        g.save()
        instance.gallery.add(g)
models.signals.post_save.connect(create_default_gallery, sender=Production)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文