Django query does not select related_name - python

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 %}

Related

how to get only Customer data who is logged in template profile.html but showing all Customer in django

models.py ( considering all required data ) how to get only logged in customer but it is showing all Customer
class Customer(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.TextField(max_length=50)
phone = models.CharField(max_length=15)
email = models.EmailField(max_length=100 ,default='')
password = models.CharField(max_length=500)
views.py ( considering all required done )
def profile(request):
data= Customer.objects.all()
return render(request,'profile.html' ,{'data':data})
profile.html ( considering making urls) and all doing requirement
{% if data %}
{% for d in data %}
<h2>{{ d.email }}</h2>
{% endfor %}
{% endif %}
data= Customer.objects.all()
data is a list of Customers not a single Customer, so there is no email attribute available. Calling data.email in the template returns None.
You need to loop through data in the template.
{% if data %}
{% for d in data %}
<h2>{{ d.email }}</h2>
{% endfor %}
{% endif %}

How to access child class object that inherits parent class?

I have parent class and child class, that inherits parent class. And that is okay, I can iterate with for loop. Now I want to access child class (example: 'product_type' So basically, I'm confused how we inherits stuff from child class inside the same loop...
views.py
from django.views import generic
from . models import Category
from django.shortcuts import render
class CategoryListView(generic.ListView):
model = Category
template_name = 'category_list.html'
models.py
from django.db import models
import uuid
class Category(models.Model):
name = models.CharField(max_length=100, help_text='Category name')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Categories'
class Product(models.Model):
product_name = models.CharField(max_length=255, help_text='Product name')
# product_spec = models.TextField(max_length=5000, help_text='Product specs')
product_type = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.product_name
category_list.html
{% extends 'base.html' %}
{% block body %}
{% for page in category_list %}
<li>{{ page.name }}</li>
<li>{{ page.product_name }} # <--------------- Now this is the point of
#my problem, I want to get
#product name from child
#class
#this returns empty <li>
{% endfor %}
{% endblock %}
you can to this
{% extends 'base.html' %}
{% block body %}
{% for page in category_list %}
<li>{{ page.name }}</li>
<li>{{ page.product_set.first.product_name }}
product name from child class, this returns empty <li>
{% endfor %}
{% endblock %}
First off change your product_type name to just category its way easier to understand and add an attribute related_name to it like this:
class Product(models.Model):
name = models.CharField(max_length=255, help_text='Product name')
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True, related_name='products')
then in your template
{% for category in category_list %}
{{ category.name }}
{% for product in category.products.all %}
{{ product.name}}
... other product data
{% endfor %}
{% endfior %}
product_typein Product is a ForaignKey which means their will be multiple products having same Category so their exist two solutions
make product_type in Product one to one key, with this you shuld get single name by {{ page.product.product_name }}
print list of all products of the category, you can do this by iterating page.product_set as it is a list (iterable) with for loop.

django foreign key table fields in html template

I have two tables(article,comment) are related one to many relashionship using a foreign key. I would have want in the html template list and some fields from the table one article but that I create don't work ,here the code :
models.py
class article(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
last_name = models.CharField(max_length=254)
age = models.CharField(max_length=254)
def __unicode__(self):
return str(self.id)
class comment(models.Model):
field_1 = models.CharField(max_length=100, blank=True, null=True)
field_2 = models.CharField(max_length=254)
field_3 = models.CharField(max_length=254)
field_fk= models.ForeignKey('article', blank=True, null=True)
def __unicode__(self):
return str(self.id)
views.py
def index(request):
apps = article.objects.all()
comments = comment.objects.all()
return render(request, 'index.html', {'apps':apps,'comments':comments})
html template :
{% for b in apps %}
<p>{{ b.field_1 }}</p>
<p>{{ b.field_2 }}</p>
<p>{{ b.field_3 }}</p>
{% for c in b.field_fk.comments %}
<p>{{ c.name }},{{ c.last_name}},{{ c.age}}</p>
{% endfor %}
{% endfor %}
in my example in the template don't show me name , last_name and age is empty the paragraph
You can't access the comments using just .comments. Use modelname_set. In your case it would be comments_set. Your for-loop will look like this:
{% for c in b.field_fk.comment_set.all %}
<p>{{ c.name }},{{ c.last_name}},{{ c.age}}</p>
{% endfor %}
Also, you aren't looping the correct model. apps is set to Article but in your template you are using the Comment fields (field_1, field_2...). The first part should be:
{% for article in apps %}
<p>{{ article.name}}</p>
<p>{{ article.last_name}}</p>
<p>{{ article.age}}</p>
...
Since the article is the main loop you don't to use the foreign key. The loop should use the comment_set directly:
{% for comment in b.comment_set.all %}
<p>{{ comment.field_1 }},{{ comment.field_2 }},{{ comment.field_3}}</p>
{% endfor %}
use this code
views.py :
def index(request):
comments = comment.objects.all()
return render(request, 'index.html', {'comments':comments})
HTML template :
{% for b in comments %}
<p>{{ b.field_1 }}</p>
<p>{{ b.field_2 }}</p>
<p>{{ b.field_3 }}</p>
<p>{{ b.field_fk.name }},{{ b.field_fk.last_name}},{{ b.field_fk.age}}</p>
{% endfor %}

Django - Looping over unique model field in template

I have a model which a choice field, category, which the user must enter when submitting an entry. I would like to create a view in which each category has its own heading (only once), therefore each unique category would have its own heading, and then display the title associated to each category.
models.py
class Position(models.Model):
club_functions = Choices('Corporate Relations', 'Events & Conference', 'Marketing & Operations', 'Software Development', 'Product')
title = models.CharField(max_length=50)
category = models.CharField(choices=club_functions, max_length=30, blank=False)
description = models.TextField(blank=True)
spec_q1 = models.CharField(max_length=500)
spec_q2 = models.CharField(max_length=500)
views.py
def position_list_view(request):
all_objects = Position.objects.all()
context = {
'object_list' : all_objects
}
return render(request, "exec_list.html", context)
exec_list.html
{% for object.category in object_list %}
<h3>{{ object.category }}</h3>
<p>{{ object.title }}</p>
{% endfor %}
Any ideas on how to do this?
you can use regroup
{% regroup object_list by category as category_list %}
<ul>
{% for category in category_list %}
<li>{{ category.grouper }}
<ul>
{% for position in category.list %}
<li>{{ position.title }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>

Foreign key relation in Django template

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 %}

Categories

Resources