Choicefield values fro multiple forms not being saved to model correctly

I am new to Django and have a ChoiceField form which I am using multiple times on the same html page. I have successfully saved all these values to the database. However, the values are saving incorrectly.

For example, I have a form with a Choicefield to pick APPLE or ORANGE. This form appears 3 times on the HTML page. If I select APPLE 3 times or ORANGE 3 times, the values save correctly to the database. If my choices are mixed, the values get saved as APPLE.

Any ideas on what is happening here or how to fix the issue? Please see Form, View, Model and HTML below. Cheers!

FORM:

FRUIT = (
("APPLE", "APPLE"),
("ORANGE", "ORANGE"),
    )

class SubmitFruitForm(forms.ModelForm):
preference = forms.ChoiceField(choices=FRUIT, required=False, label= '')

class Meta:
    model = user_choice
    fields = ('preference',)

VIEW:

class SubmitFruitView(TemplateView):
template_name = 'accounts/fruit.html'

def get(self, request):
    form1 = SubmitFruitForm()
    form2 = SubmitFruitForm()
    form3 = SubmitFruitForm()
    return render(request, self.template_name, {'form1': form1, 'form2': form2, 'form3': form3})

def post(self, request):
    form1 = SubmitFruitForm(request.POST)
    form2 = SubmitFruitForm(request.POST)
    form3 = SubmitFruitForm(request.POST)
    if form1.is_valid():
        post = form1.save(commit=False)
        post.user = request.user 
        post.save()
    if form2.is_valid():
        post = form2.save(commit=False)
        post.user = request.user 
        post.save()
    if form3.is_valid():
        post = form3.save(commit=False)
        post.user = request.user 
        post.save()
        return redirect('home')

    args = {
        'form1': form1,
        'form2': form2,
        'form3': form3,
           }
    return render(request, self.template_name, args)

HTML:

{% extends 'base.html' %}
<h1>Test</h1>

    {% block head %}
    <title>Test</title>
    {% endblock %}

    {% block body %}
<div class="container">
      <h1>Test</h1>
      <form method="post">
          {% csrf_token %}
          {{ form1.as_p }}
          {{ form2.as_p }}
          {{ form3.as_p }}
          <button type="submit">Submit</button>
      </form>
</div>
    {% endblock %}

MODEL:

class user_choice(models.Model):
preference = models.CharField(max_length=30)

Hi and welcome to the forum!

If you look at the HTML that Django generates, you’ll see that all your form fields have the same name and id attributes. This makes Django confused because it cannot tell which field should be associated with which form.

The solution to this is to use a different prefix for each form: https://docs.djangoproject.com/en/3.0/ref/forms/api/#prefixes-for-forms

If you’re trying to create multiple models of the same type, you might also want to look into what Django calls formsets.

I hope that helps.

2 Likes

Thanks for replying!

That seems to work now when I put the prefix in the get function and post function.

Cheers!