Reputation: 762
I'm trying to use custom CHOICE in MultipleChoiceField. I can save everything but not Employees.
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
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
So basically I added custom_choices
, because I want to show in MultipleChoiceField
Employee's names ('Adam', 'John' ,'Lucy')
and save their
employee_id
('123','321', 666').
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/')
I can see form on my page and I can choose employees, but employee_id is not saving. Only other fields task
and comment
are being saved.
There are no names in my models. I just want to show custom names for employee_id
.
That's why I need ('123','Adam') - I want to save '123' but display in my form 'Adam'
Upvotes: 0
Views: 774
Reputation: 2548
Well, the basic solution still stays the same:
queryset=Employee.objects.filter(employee_id__in=['some_id', 'other_id'])
The key point is that you should use a ModelMultipleChoiceField
.
If you want to display the names rather than the IDs, there are a couple of ways to do that, e.g. a get_name
method on the model and a custom ModelMultipleChoiceField, as described here: https://stackoverflow.com/a/3167840/1180983
So that would look roughly like this:
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'])
)
Upvotes: 1
Reputation: 2548
Your ModelForm does not know what to do with the employee field on save()
, because you do not tell it anywhere, and that field is not connected to any model. Use a ModelMultipleChoiceField instead.
If you need to restrict the choices the ModelMultipleChoiceField
allows, use the queryset
argument:
employees = forms.ModelMultipleChoiceField(
queryset=Employee.objects.filter(name__in=['Alice', 'Bob'])
)
Also, think about where to use plural and where to use singular names, so you do not confuse yourself (employees
instead of employee
above).
Upvotes: 0