无法使用MultipleChoiceField保存ManyToMany

时间:2015-06-25 10:16:03

标签: django django-models django-forms django-views

我试图在MultipleChoiceField中使用自定义CHOICE。我可以保存一切,但不能保存员工。

models.py

class Employee(models.Model):
    employee_id = models.CharField(max_length=20, unique=True)

    def __str__(self):
        return '%s' % self.employee_id


class Task(models.Model):
    employee = models.ManyToManyField(Employee, blank=True, null=True)
    task = models.CharField(max_length=100)
    comment = models.CharField(max_length=200)

    def __str__(self):
        return '%s' % self.task

forms.py

class TaskCreateForm(forms.ModelForm):

    CHOICES = (
        ('123', 'Adam'),
        ('321', 'John'),
        ('666', 'Lucy'),
    )

    employee = forms.MultipleChoiceField(choices=CHOICES, required=True)


    def __init__(self, custom_choices=None, *args, **kwargs):
        super(TaskCreateForm, self).__init__(*args, **kwargs)
        if custom_choices:
            self.fields['employee'].choices = custom_choices

    class Meta:
        model = Task

所以基本上我添加了custom_choices,因为我希望在MultipleChoiceField员工的姓名中显示('Adam', 'John' ,'Lucy')并保存他们的

employee_id(' 123',' 321',666')。

views.py

class TaskCreateView(CreateView):
    model = Task
    form_class = TaskCreateForm
    template_name = "task/create.html"

    def form_valid(self, form):
        self.object = form.save()
        return redirect('/task_page/')

我可以在我的页面上看到表单,我可以选择员工,但employee_id没有保存。仅保存其他字段taskcomment

澄清更新:

我的模特中没有名字。我只想显示employee_id自定义名称。 这就是我需要的原因(' 123' Adam') - 我想保存' 123'但以我的形式显示' Adam'

2 个答案:

答案 0 :(得分:1)

嗯,基本解决方案仍然保持不变:

queryset=Employee.objects.filter(employee_id__in=['some_id', 'other_id'])

关键是你应该使用ModelMultipleChoiceField

如果您想显示名称而不是ID,有几种方法可以做到这一点,例如:模型上的get_name方法和自定义ModelMultipleChoiceField,如下所述:https://stackoverflow.com/a/3167840/1180983

所以看起来大致如下:

EMPLOYEE_NAMES = {
    '123': 'Adam',
    '321': 'John',
}

class Employee(models.Model):
    employee_id = models.CharField(max_length=20, unique=True)

    def get_name(self):
        return EMPLOYEE_NAMES.get(self.employee_id, 'unknown')

class EmployeeMultipleChoiceField(ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.get_name()

class TaskCreateForm(forms.ModelForm)
    employees = EmployeeMultipleChoiceField(
        queryset=Employee.objects.filter(employee_id__in=['123', '321'])
    )

答案 1 :(得分:0)

您的ModelForm不知道如何处理save()上的员工字段,因为您没有在任何地方告诉它,并且该字段未连接到任何模型。请改用ModelMultipleChoiceField

如果您需要限制ModelMultipleChoiceField允许的选项,请使用queryset参数:

employees = forms.ModelMultipleChoiceField(
    queryset=Employee.objects.filter(name__in=['Alice', 'Bob'])
)

另外,请考虑使用复数的位置以及使用单数名称的位置,这样您就不会混淆自己(employees而不是上面的employee)。