query and display the data in template - django

models.py
class ReportType(models.Model):
report = models.ForeignKey(Report)
title = models.CharField('Incident Type', max_length=200)
type = models.ForeignKey(Types, null=False, default=False)
class Types(models.Model):
user = models.ForeignKey(User, null=True)
title = models.CharField('Incident Type', max_length=200)
parent_type_id = models.CharField('Parent Type', max_length=100, null=True, blank=True)
is_active = models.BooleanField('Is Active', default=True)
views.py
def method(request):
report_types = ReportType.objects.filter(report=int(report_id)).select_related("type")[:3]
return{'what_tab': report_types,}
template.html
{% if leftbar.what_tab.0.type.title%}{{ leftbar.what_tab.0.type.title}}{%endif%}
I am storing the integer value in type column in ReportType model.
I am able to display the 1st item alone into template.I don't know how to display all the saved item into template.
Need help.
Thanks

I dont know what leftbar is, but assuming you got all the other stuff right,
{% for tab in leftbar.what_tab %}
{% if tab.type.title %}
{{ tab.type.title}}
{% endif %}
{% ifnotequal forloop.counter leftbar.what_tab %},{% endnotifequal %}
{% endfor %}
Since title is not nullable, {% if tab.type.title %} should never be the case.

Related

Django printing dynamic field in template

With a given model:
class Ventas(models.Model):
producto = models.CharField(max_length=200, help_text="", blank=True, null=True)
stock = models.IntegerField(help_text="Tier", blank=True, null=True)
marca = models.ForeignKey(Marcas, help_text="Usuario", blank=True, null=True, on_delete=models.CASCADE)
categoria = models.ImageField(upload_to='', default="", blank=True, null=True)
def __str__(self):
return str(self.producto )
I annotate a queryset using a dynamicaly chosen field as follows:
ventas_producto = ventas.values(ver_por_choices).annotate(
uds_totales=F("uds_totales"),
share=F("uds_totales"),
).order_by('-uds_totales')
The var "ver_por_choices" can take values of the fields of the model: producto, stock, marca or categoria
Then in the template I want to print the values as
{% for venta in ventas_producto %}
<div>{{ venta.uds_totales}}</div>
<div>{{ venta.share}}</div>
{% endfor %}
How can I print the dynamic field?
Why not include it in the queryset as key:
ver_por_choices = 'Some field name'
ventas_producto = ventas.values(ver_por_choices).annotate(
uds_totales=F('uds_totales'),
share=F('uds_totales'),
key=F(ver_por_choices)
).order_by('-uds_totales')
or even more convenient:
ventas_producto = ventas.values(
uds_totales=F('uds_totales'),
share=F('uds_totales'),
key=F(ver_por_choices)
).order_by('-uds_totales')
Then you can usse this in the {% for … %} loop with:
{% for venta in ventas_producto %}
<div>{{ venta.key }}</div>
<div>{{ venta.uds_totales}}</div>
<div>{{ venta.share}}</div>
{% endfor %}

nothing is displayed on the page with all products in Django

There is a model with three classes of category-subcategory-products
class Category(models.Model):
name_category = models.CharField(verbose_name = 'name cat', max_length = 100, null=True)
image = models.ImageField(null=True, blank=True, upload_to="media/", verbose_name='pic')
slug = models.SlugField(max_length=160, unique=True, null=True)
def __str__(self):
return self.name_category
class Subcategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='категория', related_name='sub')
name_subcategory = models.CharField(verbose_name = 'name subcat', max_length = 100, null=True)
image = models.ImageField(null=True, blank=True, upload_to="media/", verbose_name='pic')
slug = models.SlugField(max_length=160, unique=True, null=True)
def __str__(self):
return self.name_subcategory
class Product(models.Model):
subcategory = models.ForeignKey(Subcategory, on_delete=models.CASCADE, verbose_name='категория',related_name='prod')
name_product = models.CharField(verbose_name = 'name product', max_length = 100, null=True)
image = models.ImageField(null=True, blank=True, upload_to="media/", verbose_name='pic')
price = models.IntegerField('price')
def __str__(self):
return self.name_product
views.py
class CategoryView(ListView):
"""all category"""
model = Category
class CategoryDetailView(DetailView):
"""all sub category"""
model = Category
class SubcategoryView(ListView):
"""all product"""
model = Subcategory
url.py
urlpatterns = [
path("", views.CategoryView.as_view()),
path('<slug:slug>/', views.CategoryDetailView.as_view(), name='category_detail'),
path('<slug:slug>/<slug:slug_sub>/', views.SubcategoryView.as_view(), name='subcategory_list'),
]
page template from which I go to the page with all products (category_detail.html)
{% extends 'base.html' %}
{% block content %}
<h2>{{ category.name_category }}</h2>
{% for sub in category.sub.all %}
{{sub.name_subcategory}}
<img src="{{sub.image.url}}" width="100px" height="100px">
{% endfor %}
{% endblock %}
page template (subcategory_list.html) with all products (here I did not write the output of the products because even the name of the subcategory is not transmitted)
{% extends 'base.html' %}
{% block content %}
{{sub.name_subcategory}}
{% endblock %}
I just can’t understand why it doesn’t display anything on the last page. Perhaps the problem is in the classes in views since previously tried to write only through functions
By default, on DetailView, Django sends an object to the context and therefore that's what you should access in your template. You can see it here
{% extends 'base.html' %}
{% block content %}
<h2>{{ object.name_category }}</h2>
{% for sub in object.sub.all %}
{{ sub.name_subcategory }}
<img src="{{ sub.image.url }}" width="100px" height="100px">
{% endfor %}
{% endblock %}
You also will need a SubCategoryDetailView if you want to see details of that. If you want to override how Django passes data to the context, you can declare context_object_name with whatever you like. Please also have a look here

Search function returning nothing -Django

def Search(request):
if request.method == 'GET' and request.GET['x']:
parameter = request.GET['x']
results = Category.objects.filter(advert__Seller_Name__icontains = parameter)
return render(request, 'campusbuy/search.html', {'results': results})
else:
return render(request, 'campusbuy/search.html')
Above is my search function. When I try to search for an object in my template, it returns nothing. However, when I deliberately search for a Seller_name that's not in the db it returns the {% else %} value. Below is the template:
% extends 'campusbuy/base.html' %}
{% block content %}
{% if results %}
{% for ads in results.advert_set.all %}
<p>{{ads.Seller_Name }}</p>
<p>{{ads.Location}}</p>
<p>{{ads.Description}}</p>
<p>{{ads.Asking_Price}}</p>
{% endfor %}
{% else %}
<p>No Ad matched your search criteria.</p>
{% endif %}
{% endblock %}
Here's the models.py:
class Category(models.Model):
Name = models.CharField(max_length=20, null=True, blank=True)
Details = models.CharField(max_length=100, default="Default")
Category_Logo = models.ImageField(max_length=100, upload_to='uploads')
def __str__(self):
return self.Name
class Advert(models.Model):
HALL3 = 'HALL3'
HALL4 = 'HALL4'
HALL2 = 'HALL2'
MAIN_GATE = 'MAINGATE'
HALL1 = 'HALL1'
Location_Choices = (
(HALL3, 'Hall3'),
(HALL4, 'Hall4'),
(HALL2, 'Hall2'),
(MAIN_GATE, 'Main_gate'),
(HALL1, 'Hall1')
)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
Seller_Name = models.CharField(max_length=50, blank=False, null=False)
Phone_Number = models.CharField(max_length=11, blank=False, null=False,
help_text='<p style="color: red; font: italic 12px tahoma;">**Please input a working Phone Number that you can be contacted with on the fly</p>')
image = models.ImageField(max_length=100, upload_to='uploads')
Item = models.CharField(max_length=20, blank=False, null=False)
Location = models.CharField(max_length=10, choices=Location_Choices, default=HALL3, blank=False)
Description = models.TextField(max_length=250, blank=False, null=False)
Asking_Price = models.CharField(max_length=20, blank=False, null=False)
published_date = models.DateTimeField(blank=False, default=timezone.now)
Thank you in advance!
I still haven't understood why you've tried to include Category in the query, since you are not using it at all either in the query itself or in the template. Just query and use Adverts directly:
results = Advert.objects.filter(Seller_Name__icontains=parameter)
and iterate over it also directly:
{% for ads in results %}
<p>{{ads.Seller_Name }}</p>
<p>{{ads.Location}}</p>
<p>{{ads.Description}}</p>
<p>{{ads.Asking_Price}}</p>
{% endfor %}
Also note, you don't need the if block, because the for template tag has an [empty`](https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#for-empty) clause that is displayed if the loop was empty:
{% for ads in results %}
<p>{{ads.Seller_Name }}</p>
<p>{{ads.Location}}</p>
<p>{{ads.Description}}</p>
<p>{{ads.Asking_Price}}</p>
{% empty %}
<p>No Ad matched your search criteria.</p>
{% endfor %}

Django filter multiple foreign key relationships

I want to list all of a teacher's students that have commented on each genre of blog posts. Below is my best effort, but I duplicate student names for each genre, so if they comment on multiple scary blog posts, their names are listed multiple times. How can I list each student name once next to each genre on the teacher profile page?
Models.py
class Genre(models.Model):
name = models.CharField(max_length=200, unique=True)
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='student_profile')
username = models.CharField(max_length=128, unique=True)
teacher = models.ForeignKey('Teacher', blank=True, null=True)
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='teacher_profile')
name = models.CharField(max_length=128, blank=True, unique=True)
class BlogPost(models.Model):
genre = models.ForeignKey(Genre, on_delete=models.CASCADE, null=True)
class Comment(models.Model):
blogpost = models.ForeignKey(BlogPost, related_name='comments', on_delete = models.CASCADE, null=True)
message = CharField(max_length=1000, blank=True)
commenter = models.ForeignKey(User, related_name='comments', on_delete=models.CASCADE, null=True)
Views.py
def teacher_profile(request):
student_list = Student.objects.filter(teacher__user=request.user)
student_blogpost_list = BlogPost.objects.filter(comments__commenter__student_profile__teacher__user=request.user).distinct()
student_genre_list = Genre.objects.filter(blogpost__in=student_blogpost_list).distinct()
return render(
request,
'myapp/teacher_profile.html',
context= {'student_list':student_list, 'student_blogpost_list':student_blogpost_list, 'student_genre_list':student_genre_list},
)
teacher_profile.html
{% if student_genre_list %}
<h4>Genres</h4>
{% for genre in student_genre_list %}
Genre: {{ genre.name }} - Students:
{% for blogpost in genre.blogpost_set.all %}
{% for comment in blogpost.comments.all %}
{% if comment.commenter.student_profile in student_list %}
{{ comment.commenter.student_profile.username }}
{% endif %}
{% endfor %}
{% endfor %}
<br>
{% endfor %}
{% endif %}
I guess it can be done in following way:
student_list = Student.objects.filter(teacher__user=request.user)
student_blogpost_list = BlogPost.objects.filter(comments__commenter__student_profile__teacher__user=request.user).distinct()
data = dict()
for blogpost in student_blogpost_list:
students_usernames = list(blogpost.comment_set.filter(commenter__in=student_list).
values_list('commenter__student_profile__username', flat=True))
if blogpost.genre.name in data:
data[blogpost.genre.name].append(students_usernames)
else:
data[blogpost.genre.name] = students_usernames
for key in data.keys():
data[key] = set(data[key]) # remove duplicates from list
data variable will be equal to something like:
{'genre_1': {'username_1', 'username_2'}, 'genre_2': {'username_2', 'username_3', 'username_4'}}
My point is that there should not be a lot of logic in template. Using this approach you'll just need to iterate over result dictionary.
Nevertheless, I can't guarantee that this code is working, as I didn't set up database with the same scheme.

Check if Django Object in Many-to-Many Exists then Display Object Only

I have a list of tools that have a part added as a bundle. The bundle is listed as a part in a many-to-many field, so I need to iterate over the parts to see if the add-on product exists for the tool being displayed. If the part exists, then I want to display just the part itself. I've tried working it out with the code below and it does check if it exists, but prints out the queryset. I understand the .all() is the cause of this but I can't figure out how to check and then just display the single part. Thank you for your help.
{% for p in tool.parts.all %}
{% if 'bp-01' %}
<h3>Bundle Included:</h3>
{{ p.model_number }}
...
{% endif %}
{% endfor %}
Part Model
class Part(Timestamp):
model_number = models.ForeignKey(ModelNumber)
price = models.SmallIntegerField()
title = models.CharField(max_length=250)
slug = models.SlugField(help_text="slug-title-should-be-like-this")
description = RichTextField()
type = models.ForeignKey(Type, blank=True)
category = models.ForeignKey(Category)
Tool Model
class Tool(Timestamp):
model_number = models.ForeignKey(ModelNumber)
price = models.SmallIntegerField()
title = models.CharField(max_length=250)
slug = models.SlugField(help_text="slug-title-should-be-like-this")
description = RichTextField()
type = models.ForeignKey(Type)
category = models.ForeignKey(Category)
parts = models.ManyToManyField(Part, blank=True, related_name="parts")
Model Number Model
class ModelNumber(models.Model):
slug = models.SlugField(max_length=100, unique=True, help_text="slug-title-should-be-like-this")
class Meta:
verbose_name = 'Model Number'
verbose_name_plural = 'Model Numbers'
def __str__(self):
return self.slug
If you just have slug field on ModelNumber you can use {% if p.model_number.slug== 'bp-01' %} to check for the condition:
{% for p in tool.parts.all %}
{% if p.model_number.slug == 'bp-01' %}
<h3>Bundle Included:</h3>
{{ p.model_number }}
...
{% endif %}
{% endfor %}
Depending on how your ModelNumber model looks, you can compare the values with something like this:
{% for p in tool.parts.all %}
{% if p.model_number.number == 'bp-01' %}
<h3>Bundle Included:</h3>
{{ p.model_number }}
...
{% endif %}
{% endfor %}
This is assuming that ModelNumber looks something like this:
class ModelNumber(models.Model):
number = models.CharField(max_length=20)
....
def __str__(self):
return self.number