Foreign key relation in Django template - python

I know this question is asked before many times but I still can't solve it.
model.py
class Awb (models.Model):
awb_id = models.CharField(primary_key=True, max_length=50)
awb_shipment_date = models.DateTimeField()
awb_shipper = models.CharField(max_length=250)
awb_sender_contact = models.CharField(max_length= 50)
class History (models.Model):
history_id = models.AutoField(primary_key=True)
awb = models.ForeignKey(Awb)
history_city_hub = models.CharField(max_length=250)
history_name_receiver = models.CharField(max_length=250)
view.py
def awb_list_view(request):
data = {}
data['awb'] = Awb.objects.all()
data['history'] = History.objects.all()
return render(request, 'portal/awb-list.html', data)
templates
{% for s in awb.history_set.all %}
{{ s.awb_id }}
{{ s.history_id }}
{% endfor %}
When I tried it with this code, there is no results in templates. I want to show awb_id and history_id in templates. Could you help me?

First let's take a look at the view code...
def awb_list_view(request):
data = {}
data['awb'] = Awb.objects.all()
data['history'] = History.objects.all()
return render(request, 'portal/awb-list.html', data)
The context dictionary being passed to the template contains an item with key 'awb' and respective QuerySet Awb.objects.all().
Now let's take a look at the template for loop...
{% for s in awb.history_set.all %}
This opening for loop template tag is trying to produce a reverse set of History objects. In order to achieve this, we would need a single AWB object instance. Instead, the 'awb' variable is a QuerySet which was passed as context to the template.
If the goal of this code is to show all AWB objects with their related History objects, the following template code should be valid.
{% for awb_obj in awb %}
{% for history_obj in awb_obj.history_set.all %}
{{ awb_obj.id }}
{{ history_obj.id }}
{% endfor %}
{% endfor %}

The Awb.history_set.all only applies to one Awb object, not a queryset.
This would work:
data['awb'] = Awb.objects.first() # If the first one has history
or:
Loop through all the Awb objects in the template to access the history_set for each one.
{% for a in awb %}
awb: {{ a.awb_id }}<br>
{% for h in a.history_set.all %}
history: {{ h.history_id }}<br>
{% endfor %}
{% endfor %}

Related

no such column: student_student.course_id

I am creating a simple system using Django Sqlite but I am facing this error whenever i try to open the table as an admin in the django/admin by clicking Studends table. The error is the following:
OperationalError at /admin/student/student/
no such column: student_student.course_id
I searched allot but could not find any exact solution to my problem.
The following is my code.
views.py
from django.shortcuts import render
from .models import Student
# Create your views here.
def index(request):
return render(request, "student/index.html",{
"student": Student.objects.all()
})
index.html
{% extends "student/layou.html" %}
{% block body %}
<h2>Student information</h2>
<ul>
{% for student in Student %}
<li> {{ student.id }} Student Full Name: {{ student.f_name }}{{ student.l_name }} in {{ student.grade }} with {{ student.gpa }} in {{ student.course_id }}</li>
{% empty %}
No information entered
{% endfor %}
</ul>
{% endblock %}
models.py
from django.db import models
# Create your models here.
class Course(models.Model):
code = models.CharField(max_length=10)
course_name = models.CharField(max_length=64)
def __str__(self):
return f"Course name: {self.course_name} with course code ({self.code})"
class Student(models.Model):
f_name = models.CharField(max_length=64)
l_name = models.CharField(max_length=64)
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name= "Classes" )
grade = models.CharField(max_length=10)
gpa = models.DecimalField(max_digits=4.0, max_length=4, decimal_places=2)
def __str__(self):
return f"{self.id} Full Name: {self.f_name} {self.l_name} in {self.grade} with a gpa {self.gpa} in course {self.course_id}"
You cannot refer to Course object via Student object with that:
{{ student.course_id }}
You can get to object or it's id like that:
{{ student.course }} # returns related Course object
{{ student.course.id }} # returns related Course object's id
For future reference, you also want to make more changes:
"student": Student.objects.all()
# change to:
"students": Student.objects.all()
{% for student in Student %}
# change to:
{% for student in students %}
{% extends "student/layou.html" %}
# probably change to:
{% extends "student/layout.html" %}

Django query does not select related_name

I do have the following models in django:
class UserPayments(models.Model):
_DATABASE = "payments"
id = models.AutoField(primary_key=True)
paym_psp_id = models.ForeignKey(ConfigPSP, null=True, on_delete=models.SET_NULL)
[...]
class InvoiceNumbers(models.Model):
_DATABASE = "payments"
id = models.AutoField(primary_key=True)
inv_date = models.DateField(null=False)
inv_payment_id = models.ForeignKey(UserPayments, null=True, on_delete=models.DO_NOTHING, related_name='paym_invoice_meta')
[...]
As you can see they are related with "related_name" definition in the InvoiceNumbers model.
When I no do a query in django like:
payments = UserPayments.objects.filter(paym_user_id=user_id)
And iterate through this query in a template
{% for inv in payments %}
{% for meta in inv.paym_invoice_meta %}
{{ meta.inv_invoice_hash }}
{% endfor %}
{% endfor %}
I get the template error that pay_invoice_meta is not iterable. With a manual select statement including the left outer join I get all the results.
What am I missing here? How can I force the query to select the values from InvoiceNumbers?
Call the all method of the related object to return a QuerySet:
{% for inv in payments %}
{% for meta in inv.paym_invoice_meta.all %}
{{ meta.inv_invoice_hash }}
{% endfor %}
{% endfor %}

Django views is it possible to select only the first four elements for a specific model.item?

I have a profile model that is displaying various items.
One of those is the country attached to the profile.
Here is what happen in the view:
class ProfilePartnerListView(FormMixin, BaseProfilePartnerView, ListView):
model = ProfilePartner
context_object_name = 'profile_list'
view_url_name = 'djangocms_partner_profile:profile-list'
def get(self, request, *args, **kwargs):
context = {}
self.object_list = self.get_queryset().order_by('-date_created')
context.update(self.get_context_data(**kwargs))
context[self.context_object_name] = context['object_list']
country_for_articles = Country.objects.exclude(regions_partner_profile=None).order_by('name')
industries_qs = ProfilePartnerIndustry.objects.active_translations(
get_language()).order_by('translations__name')
budget_qs = ProfilePartner.objects.values_list('budget',
flat=True).distinct()
context['load_more_url'] = self.get_load_more_url(request, context)
context['regions_list'] = country_for_articles
context['industry_list'] = industries_qs
context['budget_list'] = budget_qs
return self.render_to_response(context)
I know, for example 'regions_list', how to return only 4 elements from it.
But the thing is, my main object 'profile_list' that I use in the template for the rendering, is displaying all the country of the item when I do:
{% for profile in profile_list %}
{% for country in profile.regions.all %}
<div class="col-xs-12">{{ country }}</div>
{% endfor %}
{% endfor %}
And some of the profiles got 5 or 6 country. I want to only display the first 4.
Is there a way of doing it?
Many thanks!
ps: region_list, industry_list and budget_list are use for categories, it has nothing to do with what I want here.
You could use slice filter for this:
{% for profile in profile_list %}
{% for country in profile.regions.all|slice:":4" %}
<div class="col-xs-12">{{ country }}</div>
{% endfor %}
{% endfor %}

Returning more than one field from Django model

How would one go about returning more than one field from a Django model declaration?
For instance: I have defined:
class C_I(models.Model):
c_id = models.CharField('c_id', max_length=12)
name = models.CharField('name', max_length=100)
def __str__(self):
return '%s' % (self.name)
which I can use, when called in a views.py function to return
{{ c_index }}
{% for c in c_index %}
<div class='c-index-item' c-id=''>
<p>{{ c.name }}</p>
</div>
{% endfor %}
from a template. This is being called in my views.py like so:
c_index = C_I.objects.all()
t = get_template('index.html')
c = Context({'c_index': c_index})
html = t.render(c)
How would I also include the c_id defined in the model above, so that I can include {{c.name}} and {{c.c_id}} in my template? When I remove the str method, I appear to get all of the results, however, it just returns blank entries in the template and will not let me reference the individual components of the object.
What you have is fine. Your template should be:
{% for c in c_index %}
<div class='c-index-item' c-id='{{ c.c_id }}'>
<p>{{ c.name }}</p>
</div>
{% endfor %}

How do I retrieve timedate from the database and display in template?

I'm a complete Python and Django noob so any help is appreciated. This is what my model looks like:
class Matches(models.Model):
id = models.AutoField(primary_key=True)
date = models.DateTimeField()
court = models.ForeignKey(Courts)
class Participants(models.Model):
id = models.AutoField(primary_key=True)
match = models.ForeignKey(Matches)
userid = models.ForeignKey(User)
games_won = models.IntegerField()
This is what my view looks like:
def index(request):
latest_matches_list = Matches.objects.all()[:5]
return render_to_response('squash/index.html', {'latest_matches_list': latest_matches_list})
return HttpResponse(output)
And my template:
{% if latest_matches_list %}
{% for matches in latest_matches_list %}
{{ match.id }}
{% endfor %}
{% else %}
<p>No matches are available.</p>
{% endif %}
Two questions:
When I do Matches.objects.all() in the shell console it returns: [<Matches: Matches object>]. Why doesn't it print out the id and date?
In the template file I'm initially trying to test printing out the id of Matches but it doesn't seem to be working. What variable do I need for {{ match.id }}. The goal is to print out the following per match:
[matchid] [date] [time] [player1_wins] [player2_wins]
1 1-1-2011 20:00 6 8
1: how would it know to print id and date out of all fields you might have?
You can define what your object returns when printed by defining __unicode__
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.unicode
# ... model class
def __unicode__(self):
return "%s %s" % (self.id, self.date)
2: In your template, you iterate over latest_matches_list with the variable matches yet you use {{ match.id }} which isn't defined. Use {{ matches.id }}.
{% for matches in latest_matches_list %}
{{ match.id }} <!-- not defined -->
{{ matches.id }} <!-- this is your variable -->
{% endfor %}

Categories

Resources