I am implementing a quiz app and I am displaying the multiple choice answers using radio buttons.
I need to group the answers per question, so I have it like this
{% for answer in quiz.quizanswer_set.all %}
<p><input type="radio" name="score[{{quiz.id}}]" value="{{answer.score}}"/>{{answer.answer}}</p>
{% endfor %}
When I hit submit, I have the POST object like this
<QueryDict: {u'score[1]': [u'10'], u'score[3]': [u'10'], u'score[2]': [u'10'], u'Get Result': [u'Submit']}>
How do I loop through the scores in a canonical way?
I have tried request.POST.getlist('score') and it returns empty list
PS. the quiz.id may not in sequence, it's from the database row id.
My current work around is:
for quiz in Quiz.objects.all():
total_score += int(request.POST.get('score[{0}]'.format(quiz.id)))
Just filter the POST keys:
for score_key in filter(lambda key:key.startswith('score'), request.POST.keys()):
total_score += int(request.POST[score_key])
Update
Thinking about it, a list comprehension would be better than filter:
for score_key in [key for key in request.POST.keys() if key.startswith('score[')]:
total_score += int(request.POST[score_key])
Update 2
Another way that I have been looking into, is keeping the name for each radio button the same (e.g. score) and then merging the quiz id with the value:
<input type="radio" name="score" value="{{quiz.id}}-{{answer.score}} />
You could then easily get a list of all scores and split the values:
for value in request.POST['score']:
quiz_id, score = value.split('-')
You are using a PHP-ism by naming the inputs score[{{quiz.id}}]. Don't do that. Just call them all score, and your browser will do the right thing by putting them all in the same POST value which you can then get via request.POST.getlist('score').
Related
I'm making a calorie counter. The user can pick from a list of Dishes (easy with a ModelMultipleChoiceField), but they also need to specify how many servings of each Dish they had, where the serving_size is a field of my Dish model.
Basically, I want it to look like this:
The problem is that in order to display the strings "4 oz servings" and "slices", I need access to the Dish model when the field is rendered.
What's the best way to do this?
I've got 2 rough ideas so far:
Create a custom Widget that will render as a checkbox AND a number input field. When the data gets deserialized, it becomes something like this:
{"dish": <Dish model>, "servings": 2.5}
Just use the regular CheckboxSelectMultiple widget, but add the Dish model itself to the template's context. That way I can do something like this:
{% for dish in form.fountain_dishes %}
{{dish}}
I ate <input type="number"> {{dish.context.serving_size}}
{% endfor %}
However, I'm not sure how to make my clean method handle this unexpected data.
I'm trying to display a list of tickets in an HTML table. The table has various headings to display various aspects of the tickets. I would like to present this same table in a bunch of different locations across my project.
I've made a single template of /templates/shared/ticket_list.html in which presents the ticket list and then I {% include %} it where I need to display this listing. Simple enough.
However, there are a couple of pages in my project where I have a Bootstrap tabbed div. I want to display this table of tickets in both tabs, but with a different set of tickets. The HTML for this essentially requires that I {% include %} my table template twice on the same HTML page.
For example:
Tab 1: "Created By User" -- a list of tickets that the current user created
Tab 2: "Assigned To User" -- a list of tickets that are assigned to the current user
In the view, I might have something like:
created_by_ticks = Ticket.objects.filter(created_by = self.request.user)
assigned_to_ticks = Ticket.objects.filter(assigned_to = self.request.user)
The problem is, in my ticket table template, how would I present both querysets since the table itself is likely expecting a single variable name, such as:
{% for t in tickets %}
<tr>...
{% endfor %}
But passing in two querysets of tickets, I now have two ticket variables of created_by_ticks and assigned_to_ticks.
Any ideas how I could use that single ticket table template, but use multiple variables, or some other solution?
You can use the with functionality of the include tag:
{% include 'shared/ticket_list.html' with tickets=created_by_ticks %}
{% include 'shared/ticket_list.html' with tickets=assigned_to_ticks %}
I've done a good bit of searching, but it doesn't seem like this particular brand of form creation is addressed anywhere.
I'm creating a search page that queries the database for the set of all elements which have attributes at or above a given threshold. Right now I have a simple form that has 5 attributes, which have 5 thresholds each, each with their own checkbox i.e.
attrib_1 X threshold 1 X threshold 2 X threshold 3 X threshold 4 X threshold 5
attrib_2 X threshold 1 X threshold 2 X threshold 3 X threshold 4 X threshold 5
... etc ...
The HTML looks something like this:
<div class= "form-inline">
<label>Attribute 1</label>
<label class="checkbox inline">
<input type="checkbox" name="attrib 1" value="1"> Very Negative
</label>
<label class="checkbox inline">
<input type="checkbox" name="attribt 1" value="2"> Negative
</label>
<label class="checkbox inline">
<input type="checkbox" name="attrib 1" value="3"> Nonfactor
</label>
<label class="checkbox inline">
<input type="checkbox" name="attrib 1" value="4"> Positive
</label>
<label class="checkbox inline">
<input type="checkbox" name="attrib 1" value="5"> Very Positive
</label>
</div>
I then search the database using the information in the GET parameters. When I display the search results, what's an elegant way to make sure the checkboxes reflect the search query? I expect that the user will check some boxes, look at the results, then check some more to refine the search and I don't want them to have to recheck all the boxes each time they submit a search.
I've considered a few way to do this. I could use if/else statements for each checkbox and fill in the checked attribute appropriately. This would work, but seems inelegant, not very DRY, and would result in a very complex template. Alternatively, in the view I could create a data structure (dict of lists or list of tuples, probably dict of lists), which would have either 'checked' or the empty string for each checkbox. This would result in a cleaner template, but I suspect there's a more properly Django/Pythonic way to do this. I also considered a custom form, but that seemed like trying to fit a square peg in a round hole.
So, what's an elegant way to make sure that check boxes on a search form are properly checked based on GET parameters?
I am assuming you are POSTing back to the page with a refresh, instead of AJAX. In which case...
I will assume (as per Django standards) that you've made all these checkboxes a part of a Django form. In that case, you can pass the forms a series of arguments (I would suggest a dictionary) that contains the initial value for all of your checkboxes.
class SearchQuery(forms.form)
#Adding an init will allow us to pass arguments to this form In
# This case, a single dictionary argument named 'context'
def __init__(self, *args, **kwargs)
checkbox_context = kwargs.pop('context')
super(SearchQuery,self).__init__(*args, **kwargs)
#Now, instead of doing a bunch of if statements, we can say that
# our dictionary passed a series of True and False keys that will
# tell us how our checkboxes should be, in their initial state
self.fields['checkbox_one'].initial = context['box1']
checkbox_one = forms.BooleanField()
So, let's say we passed context = {'box1':True} , then our checkbox would be rendered with an initial value of 'True' or 'Checked'
I can fetch the data like this.
value= mymodel.objects.get(anycondition)
OR
value= mymodel.objects.filter(anycondition)
and can send them to my template with context.
But if I want to select all the data from a table(for all users not only one) as this query does
value= mymodel.objects.all()
and send this value to my template and can see there field by field
e.g.
my table has two fields name and phone no and I use the above query( value= mymodel.objects.all()) now if i want to see all names then i can see that and if i want to see phone no. I can see that too.
I have tried this and it doesn't work and I even I do not know it is possible or not.
If it is possible then please let me know how I can do this ?
I hope you understand my question. !!
Thanks in advance
.all() will return a list of objects that represent the rows in your model. .get() only returns one object. Your template is trying to print the result of all() if it was one object.
This is the same as if you had a list and you wanted to loop through it. In your view you would do:
product = Product_attributes.objects.all()
for i in product:
print i.size
print i.color
The equvalent for the template is:
<ul>
{% for i in product %}
<li>{{ i.size }}</li>
<li>{{ i.color }}</li>
{% endfor %}
</ul>
Although this question isn't clear it seems like you are having a bit of problem with Field Lookups. It is fairly easy to learn Here is a link to get you started
Thanks to some fantastic help on a previous question I have managed to put together my query. Everything works swimmingly save one issue.
careers = Career.objects.filter(job__dwarf__user = 1).annotate(dwarves_in_career = Count('job__dwarf'))
In my view this does exactly what I want and when I loop it in my template like so:
{% for career in careers reversed %}
<li>{{ career.name }}: {{ career.dwarves_in_career }}</li>
{% endfor %}
I get what I expected. My issue is that the above code will only return the Careers that have dwarves. I need it to return all careers:
Unassigned: 1
Construction: 1
Crafting: 2
Gathering: 0
Farming: 0
is my expected results. Instead the last two rows are not there because I am filtering for the specific user. I know why it's happening, what I am trying to figure out is how to get the query to return all careers, even if their dwarf count for a particular user is 0.
I think you need to swap over your annotate and filter clauses. See the documentation on this - the way you have it, it filters the queryset, but you actually want to keep the entire queryset but just filter the annotations.
So, I eventually figured it out...
from django.db.models import Count, Q
def fortress(request):
careers = Career.objects.filter(Q(job__dwarf__user = 1) | Q(job__dwarf__user__isnull = True)).annotate(dwarves_in_career = Count('job__dwarf'))
return render_to_response('ragna_base/fortress.html', {'careers': careers})
Not exactly sure what Q is but it works!
More information here: http://www.djangoproject.com/documentation/models/or_lookups/
Basically what I am doing is finding all careers with dwarves (based on user_id) OR all careers that have no dwarves (based on null)