我需要用户只能在photo_tipo
中选择一张值为'COVER'的照片。
Models.py的一部分
class Listing(models.Model):
...
class Photo(models.Model):
PHOTO_TIPO_CHOICES = (
('GALLERIA', 'Galleria'),
('COVER', 'Cover'),
('PLANIMETRIA', 'Planimetria'),
)
photo_tipo = models.CharField(
max_length=20,
choices=PHOTO_TIPO_CHOICES,
verbose_name='Tipo immagine',
default='GALLERIA',
)
listing = models.ForeignKey(
Listing,
related_name='photos',
on_delete=models.CASCADE,
blank=True,
null=True,
)
Admin.py的一部分
class PhotoInline(admin.TabularInline):
model = models.Photo
readonly_fields = ('image_tag',)
@admin.register(models.Listing)
class ListingAdmin(admin.ModelAdmin):
inlines = [
PhotoInline,
]
我是否可以通过错误消息控制用户选择,或者如果他已经选择了COVER照片,则可以从选择列表中删除“ COVER”?
我不能在现场使用unique=True
,因为所有模特都必须有封面照片。
答案 0 :(得分:0)
根据建议,我认为您需要为列表管理员实现模型表格。我不确定是否可以使用内联,但这将是这样的:
class ListingAdminForm(forms.ModelForm):
class Meta:
model = Listing
fields = '__all__'
def clean_photos(self):
photos = self.cleaned_data['photos']
cover_photos = [
photo for photo in photos if photo.photo_tipo == 'COVER'
]
if len(cover_photos) > 1:
self.add_error('photos', forms.ValidationError('Cannot add more than one cover photo', code='more_than_one_cover'))
return photos
@admin.register(Listing)
class ListingAdmin(admin.ModelAdmin):
inlines = [
PhotoInline,
]
form = ListingAdminForm
如果这不起作用,则可以在表单上创建自定义字段,其中一个用于封面照片,而对于其他类型的照片则只允许一个字段和另一个字段。然后,您必须进行一些验证。
通常,当我发现自己在管理员中做过多的工作时,是因为我没有按应有的方式设计模型。
您是否考虑过对模型中的基数进行编码?
class Photo(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField()
class Listing(models.Model):
# Restricted to 1 cover photo by the model, add null=False if required
cover_photo = models.ForeignKey(Photo, on_delete=models.CASCADE)
# Multiple photos for gallery allowed
gallery_photos = models.ManyToManyField(Photo)
这会使您的管理代码更简单吗?