Reputation:
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:
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
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
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