限制外键关系的范围?

发布于 2024-08-05 13:02:57 字数 693 浏览 4 评论 0原文

我正在开发一个投资组合应用程序。在这个应用程序中,我有一个名为“Project”的模型,它看起来像这样:

class Project(models.Model):
    ... 
    images = models.ManyToManyField(Image)
    ...

所以,基本上,这个项目可以包含一组图像(这些图像中的任何一个也可能属于另一个项目)。

现在,我想添加的是一种指定这些“图像”之一是“lead_image”的方法。

所以我可以添加这样的内容:

class Project(models.Model):
    ... 
    images = models.ManyToManyField(Image, related_name='images')
    lead_image = models.ForeignKey(Image, related_name='lead_image')
    ...

但是,问题是在这种情况下,lead_image 可以是任何图像。我真正想要的是它成为属于该模型实例的“图像”之一。

我想我需要使用“ForeignKey.limit_choices_to”参数,但我不确定如何使用它......特别是因为第一次创建模型实例时,“”中还没有任何图像图像”目录。

任何帮助将不胜感激。

道格

I'm developing a portfolio application. Within this application, I have a model called "Project" which looks something like this:

class Project(models.Model):
    ... 
    images = models.ManyToManyField(Image)
    ...

so, basically, this Project can contain a set of images (any of these images may belong to another Project as well).

Now, what I'd like to add is a way of specifying that one of these "images" is a "lead_image".

So I could add something like this:

class Project(models.Model):
    ... 
    images = models.ManyToManyField(Image, related_name='images')
    lead_image = models.ForeignKey(Image, related_name='lead_image')
    ...

However, the problem with this is that in this case, lead_image can be ANY image. What I really want is for it to be one of the "images" that belongs to to this model instance.

I'm thinking that I need to use "ForeignKey.limit_choices_to" argument, but I'm unsure of how to use this...especially since when the model instance is first created, there won't yet be any images in the "images" directory.

Any help would be greatly appeciated.

Doug

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

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

发布评论

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

评论(2

深爱不及久伴 2024-08-12 13:02:57

如果您想在管理工具中实现限制效果,您可以重写 formfield-for-foreignkey 方法并插入您自己的过滤器。

class ProjectAdmin(admin.ModelAdmin):

    # ...

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "lead_image":
            kwargs["queryset"] = self.model.images.all()
            return db_field.formfield(**kwargs)
        return super(ProjectAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

我在这里看到的问题(仅从选取的图像中进行选取的一般思想)是,对于新模型,最初在页面加载时不会设置 model.images 。无论您使用什么服务器端技巧,您都可能会遇到这个问题。

它可以工作,但需要额外的单击:首次创建模型时,将选择 ManyToMany model.images。选择后,如果单击“保存并继续”,那么这些图像应出现在 model.lead-image FK 字段中。

您的另一个选择是覆盖默认的管理表单并创建一些自定义内容(如自定义 fancy-pants javascript 中的自定义内容,以自动更新“引导图像”字段组合框)。

If you're wanting to achieve the limiting effect in the admin tool, you can override the formfield-for-foreignkey method and insert your own filter.

class ProjectAdmin(admin.ModelAdmin):

    # ...

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "lead_image":
            kwargs["queryset"] = self.model.images.all()
            return db_field.formfield(**kwargs)
        return super(ProjectAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

The problem I see here (with this general idea of only picking from picked images) is that for new models, initially model.images won't be set when the page loads. You'll probably face this problem no matter what server-side trick you go with.

It could work, but it requires an extra click: When the model is first created the ManyToMany model.images will be picked. After picked, if "Save and Continue" is clicked, then those images should appear in the model.lead-image FK field.

Your other option would be to override the default admin form and create something custom (custom as in custom fancy-pants javascript to auto-update the 'lead image' field combo box).

明明#如月 2024-08-12 13:02:57

解决问题的另一种方法是使用带有布尔属性“is_lead_image”的中间表。

class Image(models.Model):
    ...

class Project(models.Model):
    images = models.ManyToManyField(Image, through='ProjectImage')
    ...

class ProjectImage(models.Model):
    image = models.ForeignKey(Image)
    project = models.ForeignKey(Project)
    is_lead_image = models.Boolean(default=False)

    def save(self, *args, **kwargs):
        if self.is_lead_image:
            self._default_manager.filter(project=self.project).update(is_lead_image=False)
        return super(ProjectImage, self).save(*args, **kwargs)

*注意:如果您愿意并且有访问权限,您也可以添加 is_lead_image 字段并将其直接保存到 Image 类。

Another approach to your problem is to use a intermediate table with a boolean property 'is_lead_image'.

class Image(models.Model):
    ...

class Project(models.Model):
    images = models.ManyToManyField(Image, through='ProjectImage')
    ...

class ProjectImage(models.Model):
    image = models.ForeignKey(Image)
    project = models.ForeignKey(Project)
    is_lead_image = models.Boolean(default=False)

    def save(self, *args, **kwargs):
        if self.is_lead_image:
            self._default_manager.filter(project=self.project).update(is_lead_image=False)
        return super(ProjectImage, self).save(*args, **kwargs)

*Note: If you like and if you have access you can also just add the is_lead_image field and the save directly to the Image class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文