Django Modelform的复选框SelectMultiple和ManyToManyField存在问题

Django Modelform的复选框SelectMultiple和ManyToManyField存在问题,django,django-models,django-forms,Django,Django Models,Django Forms,我对Django很陌生(实际上是4个月),我在过去的两天里一直在为这个问题挣扎,我想我犯了一些愚蠢的错误。非常感谢您的任何帮助或意见。我正在使用Django 1.3 在我的模型中 BUSINESS_GROUP = ( ('MNC','Multinational'), ('INT','International (Export/Import)'), ('DOM','Domestic/National'), ('LOC','Local'), ('VIR','V

我对Django很陌生(实际上是4个月),我在过去的两天里一直在为这个问题挣扎,我想我犯了一些愚蠢的错误。非常感谢您的任何帮助或意见。我正在使用Django 1.3

在我的模型中

BUSINESS_GROUP = (
    ('MNC','Multinational'),
    ('INT','International (Export/Import)'),
    ('DOM','Domestic/National'),
    ('LOC','Local'),
    ('VIR','Virtual'),
)

class BusinessGroup(models.Model):
    bgroup_type = models.CharField(max_length=15, choices = BUSINESS_GROUP, blank = True, null = True)

class Business(models.Model):
    business_group_choices = models.ManyToManyField(BusinessGroup, verbose_name= "Business Group")
在形式上,我有一些类似

def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
class BusinessForm(forms.ModelForm):
   business_group_choices = forms.MultipleChoiceField(label="Business Group", widget=forms.CheckboxSelectMultiple, choices=BUSINESS_GROUP)
他认为,

if request.method == 'POST':
    form = BusinessForm(request.POST, instance = business)
    if form.is_valid():
        new_business = form.save(commit=False)
        new_business.created_by = request.user
        form_values = form.cleaned_data
        new_business.save()
        assign('edit_business', request.user, new_business)
        return HttpResponseRedirect(new_business.get_absolute_url())
我会犯这样的错误

"DOM" is not a valid value for a primary key.
"INT" is not a valid value for a primary key.
等等

我发现,

但不清楚如何解释和解决这个问题

编辑: 我试着让字段null=True和/或blank=True,但我还是得到了验证错误,为什么

在整个设置上做了一些更改后,我出现了一个新错误

Select a valid choice. [u'MNC', u'INT', u'DOM', u'LOC', u'VIR'] is not one of the available choices.
新设置: 在模型中

class BusinessGroup(models.Model):
        bgroup_type = models.CharField(max_length=15)

class Business(models.Model):
    business_group_choices = models.ManyToManyField(BusinessGroup, verbose_name= "Business Group", choices=BUSINESS_GROUP)
在形式上,我有一些类似

def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
class BusinessForm(forms.ModelForm):
   business_group_choices = forms.MultipleChoiceField(label="Business Group", widget=forms.CheckboxSelectMultiple, choices=BUSINESS_GROUP)

有几件事我会改变

首先,我尽量避免使用“魔术弦”。而不是:

BUSINESS_GROUP = (
    ('MNC','Multinational'),
    ('INT','International (Export/Import)'),
    ('DOM','Domestic/National'),
    ('LOC','Local'),
    ('VIR','Virtual'),
)
我会:

#in my_app > constants.py
MNC = 0
INT = 1
DOM = 2
LOC = 3
VIR = 4

BUSINESS_GROUP_CHOICES = (
    (MNC, 'Multinational'),
    (INT, 'International (Export/Import)'),
    (DOM, 'Domestic/National'),
    (LOC, 'Local'),
    (VIR, 'Virtual'),
)
这需要对模型进行更改,我已将字段名称更改为更清晰一些:

from django.db import models

from businesses.constants import BUSINESS_GROUP_CHOICES, MNC


class BusinessGroup(models.Model):
    business_group_type = models.IntegerField(choices=BUSINESS_GROUP_CHOICES,
        default=MNC)

    def __unicode__(self):
        choices_dict = dict(BUSINESS_GROUP_CHOICES)
        return choices_dict[self.business_group_type]


class Business(models.Model):
    business_groups = models.ManyToManyField(BusinessGroup)
真正的问题在于你的状态。不只是重新定义小部件,您需要使用ModelMultipleChiceField,例如:

from django import forms

from businesses.models import BusinessGroup


class BusinessForm(forms.ModelForm):
    class Meta:
        model = Business

    business_group = forms.ModelMultipleChoiceField(queryset=BusinessGroup.objects.all(),
                                                    widget=forms.CheckboxSelectMultiple())
这就是为什么会出现主键错误。您的业务组只是一个元组。Django试图将您选择的元组中的值指定为主键,这显然是做不到的。相反,modelmultipechoicefield将做的是将所选业务组的实例与您的业务关联起来

希望这能帮到你。

好的,我说对了, 第一件事是第一件事,不要混合太多的选择,所以我的第二次尝试是完全错误的。问题就在形式上,

所以现在最终的解决方案看起来是

BUSINESS_GROUP = (
    ('MNC','Multinational'),
    ('INT','International (Export/Import)'),
    ('DOM','Domestic/National'),
    ('LOC','Local'),
    ('VIR','Virtual'),
)

class BusinessGroup(models.Model):
    bgroup_type = models.CharField(max_length=15)

class Business(models.Model):
    business_group_choices = models.ManyToManyField(BusinessGroup)
而不是

class BusinessForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
在形式上,我有一些类似

def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
def __init__(self, *args, **kwargs):
    super(BusinessForm, self).__init__(*args, **kwargs)
    self.fields['business_group_choices'].widget = forms.CheckboxSelectMultiple(choices=BUSINESS_GROUP)
class BusinessForm(forms.ModelForm):
   business_group_choices = forms.MultipleChoiceField(label="Business Group", widget=forms.CheckboxSelectMultiple, choices=BUSINESS_GROUP)
您需要在复选框selectmultiple中使用multiplechicefield

模型中的这个是完全错误的(混合了M2M和选择)


谢谢Brandon,我真的很感谢你的意见。我认为你的解决方案很好,我在两天后意识到,最后把你的一些想法和我的混合在了一起。伟大的学习虽然感谢阿加尼认为魔术字符串比更神奇的数字更好。假设有人必须将数据库移植到其他系统。哪一个更容易计算——4对应于一个常量
VIR
,它对应于“Virtual”,或者一个字段本身中实际有“VIR”的记录?实际上,如果你讨厌神奇的字符串,你应该创建一个名为BusinessGroupType的模型。您能否提供一个令人信服的理由,说明为什么
1
是一个本质上比
INT
更有价值的数据单位。我想你是对的,1没有比INT更多的值。但是,元组不能由键引用,因此“INT”的1可以用于检索值的双重目的。事后看来,最好为BusinessGroupType创建一个模型。