Django 1.7:如何使ManyToManyField需要? [英] Django 1.7: how to make ManyToManyField required?
问题描述
我有一个Django模型,其中包含 ManyToManyField
。我需要用户在此字段中至少选择一个M2M值。
I have a Django Model with ManyToManyField
in it. I need to require user to select at least one M2M value in this field.
我尝试设置 blank = False
到M2M领域,但没有帮助。
I tried to set blank=False
to M2M field but it didn't help.
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
定义或覆盖 save()
方法 Person
model。
I can solve this situation with custom Form
definition or with override save()
method for Person
model.
是否可以防止创建 Pers在
中,至少选择一个技能
,并设置 ManyToManyField
选项?或者我需要创建自定义逻辑来处理这种情况?谢谢。
Is it possible to prevent create Person
without at least one Skill
selected, with set ManyToManyField
options? Or I need to create custom logic to handle this situation? Thanks.
我使用 Django 1.7
和 Python 3.4
更新1。如何创建 ModelForm
来控制M2M?因为在 clean_data
中,我只传递了 Person
形式的字段,并且没有我作为M2M传递的数据领域。我尝试在管理站点中创建对象,并控制选择技能
。我通过 inline
进入技能
。
Update 1. How to create ModelForm
to control M2M? Because in cleaned_data
I have only fields that I pass for Person
form, and haven't data that I pass as M2M fields. I try to create object in Admin Site and control that Skills
selected. I enter Skill
's via inline
.
# admin.py
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
extra = 2
class PersonAdmin(admin.ModelAdmin):
inlines = [PersonSkillsInline]
admin.site.register(Person, PersonAdmin)
推荐答案
在数据库级别...不,这是不可能的。
On a database level... no, that's not possible. Any enforcement of this will have to come from your application logic.
原因是每个m2m关系都有一个外键 的记录, m2m关系的双方。 SQL不能执行关系的引用方的存在,仅仅是关系的引用端。
The reason is that every m2m relation has a record with a foreign key to both sides of the m2m relation. SQL cannot enforce the existence of the referencing side of a relationship, only of the referenced side of a relationship.
此外,您也不能在模型中强制执行,因为必须创建和保存 Person
,然后才能分配多对多关系。
Furthermore, you can't enforce it in your model either, because the Person
has to be created and saved before you can assign any many-to-many relations.
您唯一的选择是以表单或视图执行。
Your only options are to enforce it in the form or the view.
在 InlineModelAdmin
这可以很容易地通过指定 min_num
(1.7 +):
In an InlineModelAdmin
this can easily be done by specifying min_num
(1.7+):
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
min_num = 1
extra = 2
这篇关于Django 1.7:如何使ManyToManyField需要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!