Show manytomany field in Django list view - django

I am trying to show the values of a manytomany field called teachers in a Django ListView.
At present my model looks like this:
class Classform(models.Model):
# Fields
name = models.CharField(max_length=255)
slug = extension_fields.AutoSlugField(populate_from='name', blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
# Relationship Fields
school = models.ForeignKey('eduly.School', default=1)
teachers = models.ManyToManyField('eduly.Teacher', )
My ListView looks like this:
class ClassformListView(GroupRequiredMixin, ListView):
model = Classform
group_required = [u"school_admin"]
login_url = "/login/"
raise_exception = True
And my template for the list view looks like this:
<tr>
<td>{{object.pk}}</td>
<td>{{object}}</td>
<td>{{ object.name }}</td>
<td>{{ object.teachers }}</td>
<td>{{ object.created }}</td>
<td>{{ object.last_updated }}</td>
</tr>
When this code runs the displayed value for object.teachers is appname.Teacher.None
I have noticed that Django has created a table called appname_classform and also a table called 'appname_classform_teachers' (presumably for the manytomany field) but I am not sure how I need to change object.teachers to get the name of the teachers. The 'appname_classform_teachers' contains valid entries for teachers in the app name_teachers table.

Use object.teachers.all instead to get the actual queryset.
-- EDIT --
To render these in a custom way:
{% for objs_teacher in object.teachers.all %}
<p>{{ objs_teacher.first_name }}</p>
<p>{{ objs_teacher.last_name }}</p>
...
{% endfor %}
You can access the indevidual fields in the loop to make it look how you want.

Related

How to get two models data in for loop with filter: Django

I do have two model as below, like patient details model and patient visit model. I want to list the visits of all patients (if exist). in views.py I am passing both models data by get all. how to filter and show it in the template by using for loop. I am using two for loop it shows total number of patient multiply total number of visit which is wrong..
class patientprofile(models.Model):
pat_Fname = models.CharField(max_length=100)
pat_Lname = models.CharField(max_length=100, blank=True)
def IntegerField(self):
return self.id
class visits(models.Model):
pat_ID = models.ForeignKey(patientprofile, on_delete=models.CASCADE)
visit_date = models.DateField(blank=False, null=False)
visit_time = models.TimeField(blank=False, null=False)
views.py
#login_requireddef visitslist(request):
patpro=patientprofile.objects.all()
vis=visits.objects.all()
return render(request, 'pmp/visitslist.html', {'vis':vis, 'patpro':patpro})
Template as below
{% for a in vis %}
<tr>
<td>
{{ a.visit_time }}
</td>
<td>{{ a.visit_date }}</td>
<td>{{ patpro.id }}</td>
<td>{{ patpro.pat_Fname }}</td>
</td>
</tr>
{% endfor %}
You can easily transform it into a dict object using values() function in queryset object.
for example:
merged_tables_dict = visits.objects.values('visit_date', 'visit_time', 'pat_ID__pat_Fname', 'pat_ID__pat_Lname')
That will return a list of objects with all data in values params
You can read more about it Django Docs values

Django Template Tagging inserting a single value from a ListView

So I am undertaking a website project and I am having some issues with one page.
I essentially load NBA teams wins and losses onto a page and make my own makeshift standings ladder.
The data loaded from my model is as follows:
MODEL.PY
from django.db import models
from django.utils import timezone
# Create your models here.
class Team(models.Model):
team_name = models.CharField(max_length=500, unique=True, primary_key=True)
wins = models.PositiveIntegerField()
losses = models.PositiveIntegerField()
created_date = models.DateTimeField(default=timezone.now)
I use the ListView in my views.py file as follows:
VIEWS.PY
class LadderListView(LoginRequiredMixin, ListView):
#this defaults to looking for the models name html so in this case team_list.html
# so i changed it to template_name variable
template_name = 'merchbet/ladder_list.html'
model = models.Team
and render the urls.py file as follows:
path('ladder/', views.LadderListView.as_view(), name='ladder_list'),
all of this successfully works.
When I get to my html code I am able to the teams, and their win/loss records to print to the website with template tagging, but I am looking to inject one line at the bottom which shows the "Last Updated: {{ team.created_date }}.
This is not working and I am not getting an errors, the "{{ team.created_date }}" just shows nothing on the url page.
I have looked through the docs and can not see what I am doing wrong.
This is my html code:
LADDER_LIST.HTML
{% extends 'merchbet/base.html' %}
{% block content %}
<div class="container">
<table>
<tbody>
<tr>
<td>Team</td>
<td>Wins</td>
<td>Losses</td>
</tr>
{% for teams in object_list %}
<tr>
<td>{{ teams.team_name }}</td>
<td>{{ teams.wins }}</td>
<td>{{ teams.losses }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 style="color:white;"> testing {{ team.created_date }}</h2>
{% endblock %}
Thanks for any help in advance.
You don't have anything called team in your template.
If you just want to display the value from a single team in the lst, and don't care which one, just grab the first or last:
{{ object_list.0.created_date }}
you just need to edit your models and that should fix your problem
class Team(models.Model):
....
created_date = models.DateTimeField(auto_now=False, auto_now_add=True) #when you first add team
updated = models.DateTimeField(auto_now=True, auto_now_add=False) #when you update
class Meta :
ordering = ["-updated","created_date"]

How to filter users using UserProfile field in Django 1.7?

I am using Django 1.7, Pyton 3.4 and PostgreSQL 9.1.
I have problem with filtering users using field from UserProfile.
Here is my UserProfile in models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
is_agency = models.BooleanField(blank=False, default=False)
customer_linked = models.ForeignKey(Customer, null=True, blank=True)
I can add now new user, but I would like to display list of users that in profile are 'is_agency' checked and Customer's name that is in ForeignKey.
I am struggling with my view:
def agency_list(request):
users = UserProfile.objects.filter(is_agency = True)
return render_to_response('agency/list.html', {'users': users}, context_instance=RequestContext(request))
and my template is:
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td> --here Customer's name--</td>
</tr>
{% endfor %}
Any ideas how can I fix my view.py and list.html?
Thanks
Leave the view as is and change the template to:
{% for profile in users %}
<tr>
<td>{{ profile.user.username }}</td>
<td>{{ profile.customer_linked.name }}</td>
</tr>
{% endfor %}
Side note: to increase speed and reduce the number of DB hits use the select_related() method:
users = UserProfile.objects.select_related().filter(is_agency=True)

django - legacy DB and inner joins

I have the following models -
class Schmst(models.Model):
schmst_proddt = models.DateTimeField(primary_key=True)
class Meta:
managed = False
db_table = 'schmst'
class Owner(models.Model):
owner_id = models.IntegerField(primary_key=True)
owner_name = models.CharField(max_length=30, blank=True)
class Meta:
managed = False
db_table = 'owner'
class Jobmst(models.Model):
jobmst_id = models.IntegerField(primary_key=True, db_column='jobmst_id', to_column='jobmst_id')
jobmst_type = models.SmallIntegerField()
jobmst_name = models.TextField(blank=True)
class Meta:
managed = False
db_table = 'jobmst'
class Jobrun(models.Model):
jobrun_id = models.IntegerField(primary_key=True)
jobmst_id = models.ForeignKey(Jobmst, db_column='jobmst_id', to_field='jobmst_id')
jobmst_type = models.SmallIntegerField(blank=True, null=True)
jobrun_proddt = models.ForeignKey(Schmst, db_column='jobrun_proddt', to_field='schmst_proddt')
jobrun_owner = models.ForeignKey(Owner, db_column='jobrun_owner', to_field='owner_id')
class Meta:
managed = False
db_table = 'jobrun'
From there I have a view that doesn't seem to be doing any joining.
def hungjobs(request):
template_vars['jobrun'] = Jobrun.objects.db_manager('Admiral').prefetch_related('jobmst_id__owner_id').filter(jobrun_status=51, jobrun_duration__gt=1800, jobmst_type__in=[2, 6])
t = get_template('queries\HungJobs.html')
c = Context(template_vars)
return HttpResponse(t.render(c), mimetype="text/html")
The results from there I want to parse into my template below -
<table border="1">
<tr>
<td>Owner</td>
<td>Production Date</td>
<td>Job ID</td>
<td>Duration</td>
<td>Job Name</td>
</tr>
{% for jobrun in jobrun %}
<tr>
<td>{{ jobrun.owner_name }}</td>
<td>{{ jobrun.jobrun_proddt|date:"M d, Y" }}</td>
<td>{{ jobrun.jobrun_id }}</td>
<td>{{ jobrun.jobrun_duration }}</td>
<td>{{ jobrun.jobmst_name }}</td>
</tr>
{% endfor %}
</table>
Currently only the jobrun_id and jobrun_duration are loading into the template because the values are in the model I'm directly querying. The foreignkey relationships however don't seem to be working and I'm unsure why as from everything I've checked they're designed properly.
I haven't ran your code but I see a few mistakes:
For loop variable name should be changed [or you can change the template variable name] from jobrun to jobruns. It's not a good practice to reuse variable names this way.
You need to specify what field of the foreign key needs to be printed in the template. Something like:
{{ jobrun.jobrun_proddt.schmst_proddt|date:"M d, Y" }}
for the date. As it stands right now, you are returning the objects and not a specific field of the foreign key objects.

Displaying ManyToMany Fields in Django Template

Model:
class Specialization(models.Model):
SPECIALIZATION_TYPE = (
('S','Specialty'),
('Ss','Sub-specialty')
)
specialization_desc = models.CharField('Specialization',max_length=50,unique=True)
specialization_type = models.CharField(max_length=2, choices=SPECIALIZATION_TYPE)
active = models.BooleanField('Active',default=True)
def __unicode__(self):
return self.specialization_desc
class Person(models.Model):
GENDER = (
('M','Male'),
('F','Female'),
)
first_name = models.CharField("First Name", max_length=50)
last_name = models.CharField("Last Name",max_length=50)
middle_name = models.CharField("Middle Name", max_length=50, blank=True)
specialization_id = models.ManyToManyField(Specialization,
Template:
{% for per in person_list%}
<tr>
<td>{{ per }}</td>
{% for spec in per.specialization_id.all %}
<td>{{ spec }}</td>
{% endfor %}
</tr>
{% endfor %}
View:
p = Person.objects.all()
return p
I would Like to see a table like this:
FullName | Specialization |
My Name | Programming, Web Development |
I'm getting this instead
FullName | Specialization |
My Name | Programming | Web Development
Storing spec in a variable is not possible accdg to articles that I've read, that alone should have solved my problem
Storing data in dictionary from views is giving me object Person is not callable
Seems a dead end for me. Ideas?
I don't get your question.
Do you get the specializations in template and only need to display them differently?
{% for person in person_list%}
<tr>
<td>{{ person }}</td>
<td>{{ person.specialization_id.all|join:", " }}</td>
</tr>
{% endfor %}
Furthermore, don't suffix foreign keys and many-to-many relations with _id.
For foreign keys Django does it for you already, so in DB you end up with field_id_id.
For many-to-many a separate table is created and the specialization_id isn't created anywhere in the DB. Use more verbose name, like specializations instead.