无法使用 MultipleChoiceField 保存 ManyToMany
Can't save ManyToMany using MultipleChoiceField
我正在尝试在 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 没有保存。仅保存其他字段 task
和 comment
。
澄清更新:
我的模型中没有名字。我只想显示 employee_id
的 自定义 名称。
这就是为什么我需要 ('123','Adam') - 我想保存 '123' 但在我的表单中显示 'Adam'
您的 ModelForm 不知道如何处理 save()
上的员工字段,因为您没有在任何地方告诉它,而且该字段未连接到任何模型。请改用 ModelMultipleChoiceField。
如果您需要限制 ModelMultipleChoiceField
允许的选择,请使用 queryset
参数:
employees = forms.ModelMultipleChoiceField(
queryset=Employee.objects.filter(name__in=['Alice', 'Bob'])
)
另外,想一想什么地方用复数,什么地方用单数,别搞混了(employees
而不是上面的employee
)。
嗯,基本的解决方案还是一样的:
queryset=Employee.objects.filter(employee_id__in=['some_id', 'other_id'])
关键是你应该使用ModelMultipleChoiceField
.
如果您想显示名称而不是 ID,有几种方法可以做到这一点,例如模型上的 get_name
方法和自定义 ModelMultipleChoiceField,如下所述:
所以这看起来大致像这样:
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'])
)
我正在尝试在 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 没有保存。仅保存其他字段 task
和 comment
。
澄清更新:
我的模型中没有名字。我只想显示 employee_id
的 自定义 名称。
这就是为什么我需要 ('123','Adam') - 我想保存 '123' 但在我的表单中显示 'Adam'
您的 ModelForm 不知道如何处理 save()
上的员工字段,因为您没有在任何地方告诉它,而且该字段未连接到任何模型。请改用 ModelMultipleChoiceField。
如果您需要限制 ModelMultipleChoiceField
允许的选择,请使用 queryset
参数:
employees = forms.ModelMultipleChoiceField(
queryset=Employee.objects.filter(name__in=['Alice', 'Bob'])
)
另外,想一想什么地方用复数,什么地方用单数,别搞混了(employees
而不是上面的employee
)。
嗯,基本的解决方案还是一样的:
queryset=Employee.objects.filter(employee_id__in=['some_id', 'other_id'])
关键是你应该使用ModelMultipleChoiceField
.
如果您想显示名称而不是 ID,有几种方法可以做到这一点,例如模型上的 get_name
方法和自定义 ModelMultipleChoiceField,如下所述:
所以这看起来大致像这样:
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'])
)