2

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

任何帮助都会非常受欢迎。

道格

4

2 回答 2

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 以自动更新“引导图像”字段组合框)。

于 2009-09-21T22:22:22.293 回答
2

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

于 2009-09-21T21:49:56.773 回答