Django 1.7:如何使ManyToManyField需要? [英] Django 1.7: how to make ManyToManyField required?

查看:138
本文介绍了Django 1.7:如何使ManyToManyField需要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆