python-在Django管理中验证ManyToManyField项的数量(带有中间模型)
作者:互联网
我有一些看起来像这样的Django模型(这不是我的确切代码,而是具有相同结构的更简单的示例):
class Player(models.Model):
# Some fields here.
pass
class Team(models.Model):
players = models.ManyToManyField(Player, through='TeamPlayer')
class TeamPlayer(models.Model):
team = models.ForeignKey(Team)
player = models.ForeignKey(Player)
some_other_field = models.BooleanField()
我使用直通机制,因为链接表上有多余的列.
我的管理类看起来像这样(请注意,我正在使用嵌入式管理来添加播放器):
class TeamPlayerInline(admin.TabularInline):
model = TeamPlayer
max_num = 11
extra = 11
class TeamAdmin(admin.ModelAdmin):
inlines = [TeamPlayerInline]
admin.site.register(Team, TeamAdmin)
问题:我的问题是,在我的管理员中,我想验证一个团队中是否有11名球员.少了将导致错误.我怎样才能做到这一点?
这些是我尝试过的事情以及它们不起作用的原因:
>以团队模型的清洁方法验证球员人数.这是行不通的,因为尚未保存播放器,因此对于一个新对象,播放器始终为零.
>验证TeamAdmin使用的ModelForm的clean_players方法中的数字.此方法永远不会被调用.确实会调用其他非ManyToMany字段的类似方法.
>用上述ModelForm的clean方法验证编号.该方法被调用,但是self.cleaned_data词典中没有“玩家”条目.
有什么想法可以实现这种验证吗?我远不是Django专家,所以不要以为我已经做了所有显而易见的事情.
解决方法:
您需要在TeamPlayerInline上设置表单集.并重写该表单集中的clean方法.例如:
from django.forms.models import BaseInlineFormSet
class TeamPlayerFormset(BaseInlineFormSet):
def clean(self):
"""Check that exactly 11 players are entered."""
super(TeamPlayerFormset, self).clean()
if any(self.errors):
return
count = 0
for cleaned_data in self.cleaned_data:
if cleaned_data and not cleaned_data.get('DELETE', False):
count += 1
if count != 11:
raise forms.ValidationError('You must enter 11 team players.')
class TeamPlayerInline(admin.TabularInline):
model = TeamPlayer
max_num = 11
extra = 11
formset = TeamPlayerFormset
class TeamAdmin(admin.ModelAdmin):
inlines = [TeamPlayerInline]
标签:validation,django-forms,django-admin,python,django 来源: https://codeday.me/bug/20191030/1967572.html