How to get list of multiple choices - django

I have a problem rendering a template variable for example {{ profile.speciality }}
that resulted in [u'pediatrics'] on the web page, what I actually wanted is simply
pediatrics. The data is coming from MultipleChoiceField and a CheckboxSelectMultiple
widget, because user should be able to select multiple options.
Then i used request.POST.getlist('speciality') to populate data in to the model instance,
for example:
user_profile = UserProfile(speciality=request.POST.getlist('speciality'))
I also tried to iterate over {{ profile.speciality }} in the template but what I am getting is string iteration rather than a list iteration.
I am an absolute beginner, I have no programming experience, pardon me if I did anything stupid, need help desperately, tried everything I could.
thank you

You can use this to render a MultipleChoiceField
{% for speciality in profile.speciality.all %}
{{ speciality }}
{% endfor %}

Related

django custom forms with models, also with 'choices' as values, how should I approach this problem?

django forms is giving me a pretty bad headache...
I've been struggling with this for 2 hours now.
I wanted to make a custom form for a model to be able to add objects to it and also be able to move the fields as I want to (instead of using form.as_p (or form|crispy), I wanted to put the entire form in a grid-like table using a custom pattern, not only putting one under another) but whenever I put a choicefield (which is either a choicefield or a foreignkey) their values are empty and also, 3 out of 4 formfields are actually shown, one remains the default.
It contains fields='__all__' with 3 choicefields and 1 floatfield each with a label, nothing more.
To show the forms in html I used
{% for field in form.visible_fields %}
{{ field.label_tag }}
{{ field.errors }}
{{ field }}
{{ field.help_text }}
{% endfor %}
which works well. Am I trying to solve the problem in a wrong way? I'll come back to this topic tomorrow, I'll need some rest now but I don't understand why passing a choices=TheModel # or # choices=TheModel.ojbects.all() breaks the entire thing.
Is there a website or a youtube channel that shows some solutions to those problems?
I lokoed up a bunch of sites and videos but they never access foreign keys as values to forms(dropdowns), never make grouped dropdowns (which I made and is working without custom forms).
Small update, I'm trying with 'labels' and '|as_crispy_field' tags but "exptype" is not changing. Everything else does. and its name is matched too.
https://imgur.com/a/CvP5565
( multiple screenshots attached )
Choices needs to be a tuple like this:
[
('CHOICE_ONE', 'choice_one')
]
So, you could create the choices list like this (Lets assume TheModel has a name field.)
choices = [(i.id, i.name) for i in TheModel.objects.all()]
The second value will be displayed to the user, the first one will be set in the database.
You could use a ModelChoiceField:
class FooMultipleChoiceForm(forms.Form):
foo_select = forms.ModelMultipleChoiceField(queryset=None)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['foo_select'].queryset = ...
https://docs.djangoproject.com/en/4.1/ref/forms/fields/#modelchoicefield

How do I properly compare two different models based on their field values and output the differences?

I am trying to figure out how to produce the output between two querysets that have similar fields. I have two different models where I keep identical fields, and at times I want to show the differences between these two models. I have researched and successfully used sets and lists in my python code, but I can't quite figure out how to leverage them or determine if I Can. Sets seems to strip out just the field values, and when I try to loop through my sets, it doesn't currently work because it's just the values without the keys.
Example:
class Team(models.Model):
player = models.Charfield
coach = models.Charfield
class TeamCommittee(models.Model):
player = models.Charfield
coach = models.Charfield
I want to be able to query both models at times and be able to exclude data from one model if it exists in the other. I have spent the afternoon trying to use sets, lists, and loops in my django templates but can't quite work this out. I have also tried various querysets using exclude....
I tried something like....
query1 = TeamCommittee.objects.filter(id=self.object.pk).values('coach','player')
query2 = Team.objects.filter(id=self.object.pk).exclude(id__in=query1)
When I use the approach above, I get TypeError: Cannot use multi-field values as a filter value.
I am wondering if I can do this via a query or if I need to dump my querysets and go down a path of manipulating a data dictionary? That seems extreme for what I am trying to do though. This does seem to be a bit more complicated because I am trying to cross reference two different models. If it was the same model this would be a lot easier but it's not an option for this particular use case.
Thanks in advance for any thoughts on the right way to approach this.
If you want to compare on the basis of the ID of both tables, probably you can use this:
teamID = list(Team.objects.all().values_list('id', flat=True))
query1 = TeamCommittee.objects.filter(id__in=teamID)
teamCommitteeID = list(TeamCommittee.objects.all().values_list('id', flat=True))
query2 = Team.objects.filter(id__in=teamCommitteeID)
I was super close...Instead I just did this...
query1 = TeamCommittee.objects.filter(id=self.object.pk).values('coach','player').distinct()
Then in my template I did a very simple....
{% for item in query1.all %}
item
{% endfor %}
Then when I wanted to get the values out of the other queryset I just did the same thing with the loop.
query2 = Team.objects.filter(id=self.object.pk).values('coach','player').distinct()
Then in my template I did a very simple....
{% for item in query2.all %}
item
{% endfor %}
Sometimes simplicity is hard.
The answer above after additional testing only partially worked. I ultimately abandoned that approach and instead incorporated the logic below into my template. I did not need to create separate queries, I just needed to loop through the fields that were already available to me as part of the DetailView I was using....
{% for author in author_detail.author_set.all %}
{% for book in book_detail.book_set.all %}
{% if author.author_name %}
{% if book.book_name in author.book_name %}
{% if author.book_name == book.book_name %}
{% elif author.book_name != book.book_name %}
{{ author.author_name }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
Thank you to everyone who made suggestions to get me to this point.

django best practice query foreign key

I am trying to understand the best way to structure queries in django to avoid excessive database hits.
This is similar to the question: Django best practice with foreign key queries, but involves greater 'depth' in the queries.
My situation:
models.py
class Bucket(models.Model):
categories = models.ManyToManyField('Category')
class Category(models.Model):
name = models.CharField(max_length=50)
class SubCategory(models.Model):
category = models.ForeignKey(Category)
class SubSubCategory(models.Model):
subcat = models.ForeignKey(SubCategory)
views.py
def showbucket(request, id):
bucket = Bucket.objects.prefetch_related('categories',).get(pk=id)
cats = bucket.categories.prefetch_related('subcategory_set__subsubcategory_set',)
return render_to_response('showbucket.html', locals(), context_instance=RequestContext(request))
and relevant template:
{% for c in cats %}
{{c}}
<ul>
{% for d in c.subcategory_set.all %}
<li>{{d}}</li>
<ul>
{% for e in d.subsubcategory_set.all %}
<li>{{e}}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
{% endfor %}
Despite the use of prefetch_related(), I seem to be hitting the database each time the top two for statements are evaluated, e.g. {% for c in cats %}, (at least I believe so from reading the debug_toolbar). Other ways I've tried have ended up with (C x D x E) number of database hits. Is this something inherently wrong with my use of prefetch, queries, or models? What is the best way in Django to access database objects with a "depth > 1" so-to-speak?
Use select_related() instead:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_related
bucket = Bucket.objects.select_related('categories',).get(id=id)
cats = bucket.categories.select_related('subcategory_set__subsubcategory_set',)
So, i found out there's a couple things going on here:
First, my current understanding on select_related vs prefetch_related:
select_related() follows foreign-key relationships, causing larger result sets but means that later use of FK won't require additional database hits. It is limited to FK and one-to-one relationships.
prefetch_related() does a separate lookup for each relationship and joins them in python, and is means to be used for many-to-many, many-to-one, and GenericRelation and GenericForeignKey.
By the book, I should be using prefetch(), as I was not 'following' the Foreign Keys.
That's what I had understood going into this, but my template seemed to be causing additional queries when evaluating the given for loops in the template, even when I added the use of {with} tags.
At first, I had thought I had discovered something similar to this issue, but I am unable to replicate when I built out my simplified example. I switched from using the debug toolbar to direct checking using the following template code (in the article Tracking SQL Queries for a Request using Django by Karen Tracey, I would link but am link-limited):
{% with sql_queries|length as qcount %}
{{ qcount }} quer{{ qcount|pluralize:"y,ies" }}
{% for qdict in sql_queries %}
{{ qdict.sql }} ({{ qdict.time }} seconds)
{% endfor %}
{% endwith %}
Using this method, I am only seeing 5 queries for using pre-fetch() (7 with debug_toolbar), and queries grow linearly when using select_related() (with +2 for debug_toolbar), which I believe is expected.
I will gladly take any other advice/tools on getting a handle on these types of issues.

django custom form template checkbox question

Django forms are really easy and nice to style especially if you like to take control of the outcome.
A question. Is there anyway you can see whether the {{ field }} type, ie checkbox, radio etc?
you could create a field_type template filter
{{ field|field_type }} = CharField
{{ field|widget_type }} = TextInput
heres a great example :
http://olivergeorge.posterous.com/django-template-tags-to-find-out-field-type

Django template can't access a form field if it is inside an array

Fairly new to Django here, so I don't know if I'm just not getting it or this is a bug. Let's say I have a form class:
class SurveyTwo(forms.Form):
food = [forms.BooleanField(required=False, initial=False, label="Seafood")]
Then, in the corresponding template, I am trying to access this by typing
{{ form.food.0 }}
When I do this, I get on my page:
<django.forms.fields.BooleanField object at 0x1c5b990>
Not the "Seafood" checkbox I was looking for. I can access the label just fine by doing {{ form.food.0.label }} but the checkbox just appears as that string. Should I be able to do this or not?
Essentially what I am trying to do is to pass an array of checkboxes to my form template, rather than having to define each form variable/field. I want to do this because I'm going to have a large number of checkboxes and want to be able to lay them out in a certain order (with a 2D array), rather than define them and lay them all out manually. If I can't do the above, does anyone know of a simpler solution? Thanks.
Mark
You can register simple template tag:
from django import template
register = template.Library()
#register.simple_tag
def bound_field(form, name):
""" returns bound field """
return form.__getitem__(name)
Then in template you just use:
{% bound_field form <field_name> %}
where is name of field.
If you have dynamicly generated fields that names you don't know you can access to them via fields.keys in this case generating all fields will look like
{% for name in form.fields.keys %}
{% bound_field form name %}
{% endfor %}