Django, How to display 2 models on a Listview - django

I am working with my first Django project
**model.py**
class product(models.Model):
product_code = models.CharField(max_length=15, unique=True)
product_name = models.CharField(max_length=100)
class stock_product(models.Model):
product_code = models.CharField(max_length=15)
branch_code = models.CharField(max_length=5)
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0)
**views.py**
class productList(ListView):
model = product
template_name = 'product/product_list.html'
def get_queryset(self):
queryset = super(productList, self).get_queryset()
self.filterset = productFilter(self.request.GET, queryset=queryset)
return self.filterset.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = self.filterset
return context
**product_list.html**
{% for alist in product_list %}
<tr>
<td>{{ alist.product_code }}</td>
<td>{{ alist.product_name }}</td>
<td>{{ alist.price }}</td>
<td>{{ alist.quantity }}</td>
</tr>
{% endfor %}
Sample Data in tables
**product**
['11111','paper'
'22222','Wood']
**stock_product**
['11111','BR1',150, 10
'11111','BR2',120, 10
'11111','BR3',100, 15
'22222','BR1',50, 200
'22222','BR2',70, 200
'22222','BR3',40, 250]
I want to get price and quantity from stock_product model, we can change branch_code by user
how can we do Plese help.
Thanks, But I want display only user branch (if user branch 'BR1' display only 'BR1')

**views.py**
class productList(ListView):
model = product
template_name = 'product/product_list.html'
def get_queryset(self):
queryset = super(productList, self).get_queryset()
self.filterset = productFilter(self.request.GET, queryset=queryset)
return self.filterset.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
stock = stock_product.objects.all(). # this line added
context['filter'] = self.filterset
context['stock'] = stock # this line added
return context
Now having this you can access the stock from your template:
**product_list.html**
{% for alist in product_list %}
<tr>
<td>{{ alist.product_code }}</td>
<td>{{ alist.product_name }}</td>
<td>{{ alist.price }}</td>
<td>{{ alist.quantity }}</td>
</tr>
{% endfor %}
{% for s in stock %}
<tr>
<td>{{ s.product_code }}</td>
<td>{{ s.product_branch }}</td>
</tr>
{% endfor %}
BUT I have to just do not recommend you do this. Why? well, I suppose you want to make the match of the product_code. Except of that you should use ForeignKey on the models and so you will have a much simple code and logic:
Model:
class stock_product(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE) # this
branch_code = models.CharField(max_length=5)
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0)
And so now without modifying your view you could do this on the template to access the data:
template:
{% for alist in product_list %}
<tr>
<td>{{ alist.product_code }}</td>
<td>{{ alist.product_name }}</td>
<td>{{ alist.stock_product.branch_code }}</td>
<td>{{ alist.stock_product.quantity }}</td>
<td>{{ alist.stock_product.price }}</td>
</tr>
{% endfor %}

how about change the model with using foreign keys.
and use the django_tables2.
# **model.py**
from django.db import models
class product(models.Model):
product_code = models.CharField(max_length=15, unique=True)
product_name = models.CharField(max_length=100)
class stock_product(models.Model):
# product_code = models.CharField(max_length=15)
product = models.ForeignKey(product, on_delete=models.CASCADE)
branch_code = models.CharField(max_length=5)
quantity = models.IntegerField(default=0)
price = models.DecimalField(default=0)
this is table code for django_tables2.
class DetailedDataTable(tables.Table):
product_code = tables.Column(verbose_name='product_code', accessor='product_id')
product_name = tables.Column(verbose_name='product_name', accessor='product_id')
class Meta:
model = stock_product
template_name = "django_tables2/bootstrap.html"
fields = ('product_code', 'product_name', 'branch_code', 'quantity', 'price')
def render_product_code(self,value, record):
return product.objects.get(id=value).product_code
def render_product_name(self,value, record):
return product.objects.get(id=value).product_name
and this is view
def view(request):
template_name = 'template.html'
query_set = stock_product.objects.all()
table = DetailedDataTable(qs)
context={
'table':table,
}
return render(request, template_name, context)
and this is for template page uses.
{# tutorial/templates/tutorial/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List</title>
</head>
<body>
{% render_table table %}
</body>
</html>
:)

Related

Table not displaying a data from model

this is my views.py
def sms(request):
obj = Sms.objects.all()
return render(request, 'advisory.html', {'sms': obj})
and this is on my html.
{% for i in sms %}
<tr>
<td>{{ i.description }}</td>
<td>{{ i.timestamp }}</td>
</tr>
{% endfor %}
this is the model
class Sms(models.Model):
description = models.CharField(max_length=100, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
And i don't really know why its not returning any data from my model. please help! thanks
add to you Sms model function like this
def __str__(self):
return self.description

Regrouping in Django Template With Grouping in views

I have a model with different forginekey wish I could like to group it by student. I was successfully done that but in my template, I want to nested the result or regroup it by subject according to students.
model.py
class Result(models.Model):
examtype = models.ForeignKey(ExamType, on_delete=models.CASCADE)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
subject = models.ForeignKey(SubjectAppointment, on_delete=models.CASCADE)
test = models.FloatField()
exam = models.FloatField()
total = models.FloatField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
self.total = self.test + self.exam
super().save(*args, **kwargs)
def __str__(self):
return self.student.matricnumber
def get_result_total(self):
return int(float(f'{self.test + self.exam}'))
views.py
def ReportView(request):
template_name = 'teacher/report.html'
score = Result.objects.values('student', 'exam', 'test', 'subject__subject__name').annotate(student_totalscore=Sum('total')).annotate(attending=Count('subject'))
print(score)
context = {
'score': score,
}
return render(request, template_name, context)
report.html
{% for s in score %}
{% regroup score by s.student as student_list %}
{% for a in student_list %}
<!-- {% for b in a.list %} -->
<tr>
<td>{{ b.subject__subject__name }}</td>
<td>{{ b.test }}</td>
<td>{{ b.exam }}</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<!-- {% endfor %} -->
{% endfor %}
{% endfor %}

Display number of views for a specific post for specific user in a table using django

i want to display number of views in a table for a specific post. I already have the data stored in db. it seems that print statement print('count', context['count_view']) is working inside get_context_data method but it is not working as expected in the template. Don't worry about the data inside the image, its actually dummy data. Anyone helpenter image description here
models.py
class ObjectViewed(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
ip_address = models.CharField(max_length=220, blank=True, null=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # User, Blog, or any other models
object_id = models.PositiveIntegerField() # User id, Blog id, or any other models id
content_object = GenericForeignKey('content_type', 'object_id')
timestamp = models.DateTimeField(auto_now_add=True)
views.py
class PostListView(ListView):
model = Post
template_name = 'edmin/post/postList.html'
context_object_name = 'posts'
ordering_by = ['-created']
def get_queryset(self):
post=Post.objects.filter(author=self.request.user)
return post
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
post=Post.objects.filter(author=self.request.user)
c_type = ContentType.objects.get_for_model(Post)
for p in post:
context['count_view'] = ObjectViewed.objects.filter(content_type=c_type, object_id=p.id).count()
print('count',context['count_view'])
return context
postList.html
{% for post in posts %}
{% if post.status == 'Draft' %}
{% else %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<td><a style="color:blue" href="{% url 'edmin:post_detail_view' pk=post.pk %}">{{ post.title }}</a></td>
<td>{{ post.banner_title }}</td>
<td>{{ post.created }}</td>
<td>{{ count_view }}</td>
<td>{{ post.status }}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
{% endif %}
{% endfor %}
Since context allows 'dict', you can pass all of your views through context.

create a particular detail view

i need help to formulate a query.
my models are this:
class Rider(models.Model):
id_rider = models.IntegerField(default = 0,blank= True, primary_key=True)
first_name = models.CharField(max_length = 256,blank= True)
[...]
def str(self):
return self.display_name
class Risultato(models.Model):
TYPE_CHOICES = (('SR','sr'),('ITT', 'itt'),('HC', 'hc'),('1C','1c'),('TTT','ttt'))
id_rider = models.ForeignKey(Rider,related_name='rider', on_delete=models.CASCADE)
id_stage = models.ForeignKey(Stage,related_name='team', on_delete=models.CASCADE)
type_ris = models.CharField(choices=TYPE_CHOICES,max_length = 256,blank= True)
rank = models.IntegerField(default = 0,blank= True)
punti = models.IntegerField(default = 0,blank= True)
def __str__(self):
return self.id_raider,self.id_stage,self.rank
i need to create a Detail View to details of riders, somethings like this:
-------------------------------------------
Rider: [display_name]
age : [age]
...
...
--------SCORE HISTORY-----
stage sr/itt ttt hc 1c tot
1 100 null 10 0 110
2 null 20 5 10 35
Thanks in advance!!
UPDATE
i add the view and the template, but i can't see the table
view.py:
class RiderDetails(DetailView):
model = Rider
template_name = 'game/rider_detail.html'
def get_context_data(self, *args, **kwargs):
context_data = super().get_context_data(**kwargs)
context_data['risultato_qs'] = Risultato.objects.filter(id_rider=self.object)
return context_data
rider_detail.html:
{% extends 'game/base.html'%}
{% block content %}
<h1>{{ rider.display_name }}</h1>
<table>
<tbody>
{% for risultato in risultato_qs %}
<tr>
<td>{{ risultato.stage }}</td>
<td>{{ risutato.type_ris }}</td>
<td>{{ risutato.punti }}</td>
... etc ...
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
screen page
A quick example might look like:
class RiderDetails(DetailView):
model = Rider
template_name = 'path_to_rider_template'
def get_context_data(self, *args, **kwargs):
context_data = super().get_context_data(*args, **kwargs)
context_data['risultato_qs'] = Risultato.objects.filter(id_rider=self.object)
return context_data
Then in your template you can, for example:
... Rider details here ...
<table>
<tbody>
{% for risultato in risultato_qs %}
<tr>
<td>{{ risultato.stage }}</td>
<td>{{ risutato.type_ris }}</td>
... etc ...
</tr>
{% endfor %}
</tbody>
</table>

How to filter today's date from ListView

I have models called Statistics. From views, I made a ListView to display it on the template. Now my problem is I would like to see only today's == date_expiry. How can I do this using ListView?
models.py
class Statistics(models.Model):
site = models.CharField(max_length=264)
name = models.CharField(max_length=264, blank=True)
mac_add = models.CharField(max_length=264)
minutes_used = models.CharField(max_length=265)
date = models.DateTimeField(auto_now=True, blank=True)
date_expiry = models.DateTimeField()
def __str__(self):
return self.name
views.py
class DisplayStats(ListView):
model = Statistics
ordering = ['date']
html
<table class="table">
<tr>
<th>Site</th>
<th>Name</th>
<th>Mac ID</th>
<th>Hours</th>
<th>Date</th>
<th>Date Expired</th>
</tr>
{% for clients in object_list %}
<tr>
<td>{{ clients.site }}</td>
<td>{{ clients.name }}</td>
<td>{{ clients.mac_add }}</td>
<td>{{ clients.minutes_used|cut:".0" }}</td>
<td>{{ clients.date }}</td>
<td>{{ clients.date_expiry }}</td>
</tr>
{% endfor %}
</table>
you can just filter it.
import datetime
class DisplayStats(ListView):
model = Statistics
ordering = ['date']
def get_queryset(self):
# python3
queryset = super().get_queryset()
# if python2
# queryset = super(DisplayStats, self).get_queryset()
queryset.filter(date_expiry=datetime.date.today())
return queryset
You can just filter the query set. You can do it two ways:
Override the queryset
import datetime
class DisplayStats(ListView):
model = Statistics
queryset = Statistics.objects.filter(date_expiry=datetime.date.today())
ordering = ['date']
Use get_queryset()
import datetime
class DisplayStats(ListView):
model = Statistics
ordering = ['date']
def get_queryset(self):
return Statistics.objects.filter(date_expiry=datetime.date.today())