Django 1.7:如何使 ManyToManyField 成为必需的?
Django 1.7: how to make ManyToManyField required?
我有一个包含 ManyToManyField
的 Django 模型。我需要要求用户在此字段中 select 至少一个 M2M 值。
我尝试将 blank=False
设置为 M2M 字段,但没有帮助。
class Skill(models.Model):
name = models.CharField(max_length=200)
class PersonSkills(models.Model):
person = models.ForeignKey('Person')
skill = models.ForeignKey('Skill')
class Person(models.Model):
name = models.CharField(max_length=200)
skills = models.ManyToManyField('Skill', through='PersonSkills')
p = Person(name='Bob')
p.save()
# success, but I expect that this should throw ValidationError, because I didn't select at least one Skill for this person
我可以使用自定义 Form
定义或 Person
模型的覆盖 save()
方法来解决这种情况。
是否可以在没有至少一个 Skill
selected 和设置 ManyToManyField
选项的情况下阻止创建 Person
?或者我需要创建自定义逻辑来处理这种情况?谢谢。
我用Django 1.7
和Python 3.4
更新1.如何创建ModelForm
来控制M2M?因为在 cleaned_data
中,我只有为 Person
表单传递的字段,而没有作为 M2M 字段传递的数据。我尝试在管理站点中创建对象并控制 Skills
selected。我通过 inline
输入 Skill
。
# admin.py
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
extra = 2
class PersonAdmin(admin.ModelAdmin):
inlines = [PersonSkillsInline]
admin.site.register(Person, PersonAdmin)
在数据库级别...不,那是不可能的。对此的任何强制执行都必须来自您的应用程序逻辑。
原因是每一个m2m关系在m2m关系的两边都有一个外键到的记录。 SQL 不能强制存在关系的引用端,只能强制存在关系的引用端。
此外,您也不能在模型中强制执行它,因为必须先创建并保存 Person
,然后才能分配任何多对多关系。
您唯一的选择是在表单或视图中强制执行它。
在 InlineModelAdmin
中,这可以通过指定 min_num
(1.7+) 轻松完成:
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
min_num = 1
extra = 2
我有一个包含 ManyToManyField
的 Django 模型。我需要要求用户在此字段中 select 至少一个 M2M 值。
我尝试将 blank=False
设置为 M2M 字段,但没有帮助。
class Skill(models.Model):
name = models.CharField(max_length=200)
class PersonSkills(models.Model):
person = models.ForeignKey('Person')
skill = models.ForeignKey('Skill')
class Person(models.Model):
name = models.CharField(max_length=200)
skills = models.ManyToManyField('Skill', through='PersonSkills')
p = Person(name='Bob')
p.save()
# success, but I expect that this should throw ValidationError, because I didn't select at least one Skill for this person
我可以使用自定义 Form
定义或 Person
模型的覆盖 save()
方法来解决这种情况。
是否可以在没有至少一个 Skill
selected 和设置 ManyToManyField
选项的情况下阻止创建 Person
?或者我需要创建自定义逻辑来处理这种情况?谢谢。
我用Django 1.7
和Python 3.4
更新1.如何创建ModelForm
来控制M2M?因为在 cleaned_data
中,我只有为 Person
表单传递的字段,而没有作为 M2M 字段传递的数据。我尝试在管理站点中创建对象并控制 Skills
selected。我通过 inline
输入 Skill
。
# admin.py
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
extra = 2
class PersonAdmin(admin.ModelAdmin):
inlines = [PersonSkillsInline]
admin.site.register(Person, PersonAdmin)
在数据库级别...不,那是不可能的。对此的任何强制执行都必须来自您的应用程序逻辑。
原因是每一个m2m关系在m2m关系的两边都有一个外键到的记录。 SQL 不能强制存在关系的引用端,只能强制存在关系的引用端。
此外,您也不能在模型中强制执行它,因为必须先创建并保存 Person
,然后才能分配任何多对多关系。
您唯一的选择是在表单或视图中强制执行它。
在 InlineModelAdmin
中,这可以通过指定 min_num
(1.7+) 轻松完成:
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
min_num = 1
extra = 2