我正在开发一个投资组合应用程序。在这个应用程序中,我有一个名为“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”参数,但我不确定如何使用它...特别是因为首次创建模型实例时,还没有任何图像在“images”目录中。
任何帮助都会受到很大的限制。
道格
答案 0 :(得分: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类。
答案 1 :(得分: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以自动更新'潜在客户图像'字段组合框)。