user9221735
user9221735

Reputation:

Django - Saving multiple selection boxes in one form

I need to save multiple selections in one form, but it is not saving the values to my model. This is how the form looks:

enter image description here

This is my models.py

class ChoiceManager(models.Manager):
    def rates (self, Task_id, rating2, yo):
        assignment = Assignment.objects.get(id=Assignment_id)
        rating = rating2
        yo = FiscalYear.objects.get(fy_year=years)
        for i in range(len(rating2)):
            rated = Prog_capability.objects.create(
            task = task, 
            rating2 = rating[i],
            fy = yo[i]
        )

class NewYear(models.Model):
    year = models.CharField(max_length=5)
    new_year = models.CharField(max_length=5)

class Choice(models.Model):
    rating = models.CharField(max_length=255, blank=True, null=True)
    year = models.ForeignKey(NewYear, related_name="choices")
    assignment = models.ForeignKey(Assignment, related_name="choice")
    objects = ChoiceManager()

This is my views.py

def task_rating(request, Assignment_id):
    ratings = request.POST.getlist('rating2',[])
    years= request.POST.getlist('yo",[])
    rates= Choice.objects.rates(Assignment_id, ratings, years)
    return redirect ((reverse('Project:assignment_page', kwargs={'Assignment_id': Assignment_id})))

HTML

 <form action="{% url 'project:rating' %}" method="post">
      {% csrf_token %}
      {% for year in years %}
        <li class=cap_select>
          <div id=fyc>{{year.fy_year}}</div>
          <select name="rating2" id="{{assignment.id}}-{{year.id}}">
            <option>Choose From List</option>
            <option class=hi value="high">High</option>
            <option class=med value="medium">Medium</option>
            <option class=low value="low">Low</option>
            <option class=na value="n/a">N/A</option>
          </select> 
          <input type="hidden" name="yo" value={{year.fy_year}}>
        </li>  
      {% endfor %}
        <br>
        <input id=save_cap type="submit" value="Save">
      </form> 

I'm getting a

"NewYear matching query does not exist." and cannot save the data.

I've been on this for a couple of days. Any help will be appreciated.

Upvotes: 1

Views: 2120

Answers (2)

user9221735
user9221735

Reputation:

So this is what worked in the end:

models.py

class ChoiceManager(models.Manager):
def rates (self, Assignment_id, rating2, years, rating_id):
    Assignment = Assignment.objects.get(id=Assignment_id)
    rating = rating2
    rating_id = rating_id
    for i in range(len(rating2)):
        year =NewYear.objects.get(fy_year=years[i])
        rated = Choice.objects.create(
        assignment = assignment, 
        rating = rating[i],
        fy = year,
        rating_id = rating_id[i]
    )

views.py

def task_rating(request, Assignment_id):
    ratings=  request.POST.getlist('rating2',[])
    years=  request.POST.getlist('yo',[])
    rating_id = request.POST.getlist('rating_id',[])
    rates = Choice.objects.rates(Assignment_id,ratings, years,rating_id)
    return redirect ((reverse('assignment:assignment_page', kwargs={'Assignment_id': Assignement_id})))

HTML

<form action="{% url 'project:rating' %}" method="post">
  {% csrf_token %}
  {% for year in years %}
      <select name="rating2" id="{{assignment.id}}-{{year.id}}">
        <option>Choose From List</option>
        <option class=hi value="high">High</option>
        <option class=med value="medium">Medium</option>
        <option class=low value="low">Low</option>
        <option class=na value="n/a">N/A</option>
      </select> 
      <input type="hidden" name="yo" value={{year.fy_year}}>
      <input type="hidden" name="rating_id" value="{{tasks.id}}-{{year.id}}">
  {% endfor %}
    <br>
    <input id=save_cap type="submit" value="Save">
  </form> 

Upvotes: 0

Satendra
Satendra

Reputation: 6865

Yes you are right

POST data is not coming as dictionary.

You are looping on years and rendering select and input tag inside form and the name attribute of all select and input tags are same that is rating and year simultaneously

in that case when you submit your form you will get a list of rating and year so you should use getlist() method while fetching it from request.POST QueryDict.

request.POST.getlist('rating[]')
request.POST.getlist('year[]')

if above doesn't work use it like

request.POST.getlist('rating', [])
request.POST.getlist('year', [])

Update your rates method like.

class ChoiceManager(models.Manager):
    def rates (self, Assignment_id, rating, year):
        ...
        # you can use year also to find the length
        for i in range(len(rating)): 
           rated = Choice.create(
              assignment = assignment, 
              year = year[i],
              rating = rating[i]
           )

change method call.

rates = Choice.objects.rates(Assignment_id,request.POST.getlist('rating[]'), request.POST.getlist('year[]'))

Upvotes: 2

Related Questions