Django 1.7:如何使ManyToManyField成为必需?

Ant*_*nko 3 python django web

我有一个Django模型ManyToManyField.我需要要求用户在此字段中选择至少一个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
Run Code Online (Sandbox Code Playgroud)

我可以使用自Form定义定义或使用模型的覆盖save()方法来解决这种情况Person.

是否可以通过设置选项阻止创建Person没有至少一个Skill选定的ManyToManyField?或者我需要创建自定义逻辑来处理这种情况?谢谢.

我用Django 1.7Python 3.4


更新1.如何创建ModelForm控制M2M?因为在cleaned_data我只有Person表格中传递的字段,并且没有我作为M2M字段传递的数据.我尝试在管理站点中创建对象并控制Skills所选对象.我进入了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)
Run Code Online (Sandbox Code Playgroud)

knb*_*nbk 8

在数据库级别......不,这是不可能的.任何强制执行都必须来自您的应用程序逻辑.

原因是每个m2m关系都有一个记录,其中一个外键 m2m关系的两边.SQL不能强制存在关系的引用方,只能引用关系的引用方.

此外,您也无法在模型中强制执行它,因为Person必须先创建并保存它,然后才能分配任何多对多关系.

您唯一的选择是在表单或视图中强制执行它.

InlineModelAdmin这可以通过指定min_num(1.7+)轻松完成:

class PersonSkillsInline(admin.TabularInline):
    model = Person.skills.through
    min_num = 1
    extra = 2
Run Code Online (Sandbox Code Playgroud)