【问题标题】:Limiting the scope of a ForeignKey relationship?限制 ForeignKey 关系的范围?
【发布时间】:2010-11-30 03:53:48
【问题描述】:

我正在开发一个投资组合应用程序。在这个应用程序中,我有一个名为“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”参数,但我不确定如何使用它......尤其是当模型实例首次创建时,还没有任何图像在“图像”目录中。

任何帮助将不胜感激。

道格

【问题讨论】:

    标签: django django-models foreign-key-relationship


    【解决方案1】:

    解决问题的另一种方法是使用带有布尔属性“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 类。

    【讨论】:

    • 有趣。我会试试这个。
    【解决方案2】:

    如果你想在管理工具中实现限制效果,你可以重写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 字段中。

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

    【讨论】:

    • 谢谢。这似乎是一个不错的方法。我不认为有一个“理想”的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多