I use MultipleChoiceField in my form. I want to add all selected values to database, but next code which I use add only last value which user select. I tried in my view create multiple number objects. Where I did mistake?
models.py:
class Requirement(models.Model):
code = models.UUIDField(_('Code'), primary_key=True, default=uuid.uuid4, editable=False)
symbol = models.CharField(_('Symbol'), max_length=250)
name = models.CharField(_('Name'), max_length=250)
forms.py:
class AddForm(forms.ModelForm):
symbol= forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, choices=REQUIREMENTS_CHOICES,)
class Meta:
model = Requirement
fields = ('symbol',)
REQUIREMENTS_CHOICES = (
('A', 'Name A'),
('B', 'Name B'),
('C', 'Name C'),
)
views.py:
def requirement_add(request):
data = dict()
if request.method == 'POST':
form = AddForm(request.POST)
if form.is_valid():
list = dict(REQUIREMENTS_CHOICES) # {'C': 'Name C', 'A': 'Name A', 'B': 'Name B'}
symbols = form.cleaned_data.get('symbol') # ['A', 'B', 'C']
requirement = form.save(commit=False)
for symbol in symbols:
requirement.symbol = symbol
requirement.name = list[symbol]
requirement.save()
data['form_is_valid'] = True
requirements = Requirement.objects.filter()
context = {requirement': requirement, 'requirements': requirements}
data['html_requirement'] = render_to_string('project/requirement_list.html', context)
else:
data['form_is_valid'] = False
else:
form = AddForm()
context = {'form': form}
data['html_requirement_form'] = render_to_string('project/requirement_add.html', context, request=request)
return JsonResponse(data)
You should add requirement.pk = None so that every call to save will insert a new row in the database :
for symbol in symbols:
requirement.symbol = symbol
requirement.name = group_requirement_list[symbol]
requirement.pk = None
requirement.save()
See the documentation here https://docs.djangoproject.com/en/dev/ref/models/instances/#how-django-knows-to-update-vs-insert.
Edit:
Explanation : in the first iteration of this loop requirement.save() will insert a new row in the database as you would expect. But after that requirement will have the primary key of the new row and Django will try to update it instead of creating a new one.
Alternative solution : you could avoid all of this if you put requirement = form.save(commit=False) in the for loop like this :
symbols = form.cleaned_data.get('symbol') # ['A', 'B', 'C']
for symbol in symbols:
requirement = form.save(commit=False)
requirement.symbol = symbol
requirement.name = group_requirement_list[symbol]
requirement.save()