I need to get values from model fields, multiply and display the product in template.
For example, I have this code:
models.py
class Product(models.Model):
field1 = models.IntegerField()
field2 = models.IntegerField()
def multiply(self):
return self.field1 * self.field2
views.py
def home(request):
products = Product.objects.all()
#something goes here?
context = {
'products': products
}
return render(request, 'home.html', context)
template
{% for product in products %}
{{ product.field1 }}
{{ product.field2 }}
here goes the value of field1/field2 {{ }}
{% endfor %}
How it's better to achieve this?
You can add a method on the model:
def divided_fields(self):
return self.field1 / self.field2
And then im template:
{{ product.divided_fields }}
Another possibility would be to create a custom template tag or filter that handles division as there is no default tag or filter for such operations.
You can use django-mathfilters for this.
{% load mathfilters %}
...
<h1>Basic math filters</h1>
<ul>
<li>8 + 3 = {{ 8|add:3 }}</li>
<li>13 - 17 = {{ 13|sub:17 }}</li>
{% with answer=42 %}
<li>42 * 0.5 = {{ answer|mul:0.5 }}</li>
{% endwith %}
{% with numerator=12 denominator=3 %}
<li>12 / 3 = {{ numerator|div:denominator }}</li>
{% endwith %}
<li>|-13| = {{ -13|abs }}</li>
</ul>
Related
I reach the error in my django project when I was trying to display my view. The problem seems like related to the Course model but i honestly dont know where to begin with it.
My Teacher model:
class Teacher(models.Model):
GENDER_MALE = 0
GENDER_FEMALE = 1
GENDER_CHOICES = [(GENDER_MALE, 'Male'), (GENDER_FEMALE, 'Female')]
fname = models.TextField(max_length=20)
lname = models.TextField(max_length=20)
gender = models.IntegerField(choices=GENDER_CHOICES)
phone = models.IntegerField(default=None, blank=True, null=True)
email = models.TextField(max_length=30, default=None, blank=True, null=True)
faculty = models.ForeignKey('Faculty', on_delete=models.CASCADE )
def __str__(self):
return self.lname + ' ' + self.fname
My Course model:
class Course(models.Model):
name = models.TextField(max_length=50)
faculty = models.ForeignKey('Faculty', on_delete=models.CASCADE )
def __str__(self):
return f'{self.name}'
My Faculty model:
class Faculty(models.Model):
name = models.TextField(max_length=30)
def __str__(self):
return f'{self.name}'
My view:
def teacher(request, teacher_id):
teacher = get_object_or_404(Teacher, pk=teacher_id)
faculties = Faculty.objects.filter(teacher=teacher)
course = Course.objects.filter(teacher=teacher)
classrooms = Classroom.objects.filter(teacher=teacher)
students = Student.objects.filter(teacher=teacher)
# students = []
# for cls in classrooms:
# students.extend(Student.objects.filter(classroom=cls))
return render(request, 'polls/teacher.html', {'teacher': teacher,'faculties': faculties, 'courses':course,'classrooms':classrooms, 'students':students})
When i run the website, it point out in my view the code to be stoped at course = Course.objects.filter(teacher=teacher)
My template:
{% extends "polls/base.html" %}
{% block body %}
<h2>{{ teacher.fname }} {{ teacher.lname }}</h2>
<h3>Faculty</h3>
{% if faculties %}
{% for faculty in faculties %}
<p>{{ faculty.name }}</p>
{% endfor %}
{% else %}
<p> </p>
{% endif %}
<h3>Course</h3>
{%if courses %}
{% for course in courses %}
<p>{{ course.name }} </p>
{% endfor %}
{% else %}
<p> </p>
{% endif %}
<h3>Class</h3>
{% if classrooms %}
{% for class in classrooms %}
<p>{{ class.name }} </p>
{% endfor %}
{% else %}
<p> </p>
{% endif %}
<h3>Student</h3>
{% if students %}
{% for student in students %}
<p>{{ student.fname }} {{ student.lname }}</p>
{% endfor %}
{% else %}
<p> </p>
{% endif %}
{% endblock %}
This happens because of the following line:
course = Course.objects.filter(teacher=teacher)
The Course model has no field teacher, so you can't filter by it. To fix it there are two options:
Add a field to Course:
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
and then add a Teacher to every Course that already exists (or make it null=True).
Or you can filter Course by the Faculty that the teacher is a member of, to get all courses that have a teacher that belongs to that faculty:
courses = Course.objects.filter(faculty=teacher.faculty)
Or, using reverse foreign key lookup:
courses = teacher.faculty.course_set.all()
I'm making a search bar in Django using Class-Based Views on my Views.py. When I try to get the value submitted in the input it's not showing the query name and if I don't submit anything is NOT giving me an error. Also what is the way to get the post showed by the world searched? Thanks for all. My code is:
Models.py:
class Post(models.Model): # Post core
title = models.CharField(max_length=299)
author = models.ForeignKey(User,default=ANONYMOUS_USER_ID, on_delete=models.CASCADE)
category = models.CharField(max_length=50)
image = models.ImageField(blank=True)
desc = models.TextField()
text = RichTextField(blank = True, null = True )
date = models.DateTimeField(auto_now=False, auto_now_add=True)
slug = models.SlugField(null = True, blank = True, unique=True)
class Meta: # Order post by date
ordering = ['-date',]
def __str__(self): # Display title
return self.title
def get_absolute_url(self): # #TODO da cambiare
return reverse("listpost")
Views.py:
class SearchView(TemplateView):
model = Post
template_name = "admin/search.html"
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Post.objects.filter(text__icontains=q, desc__icontains = q, title__icontains = q)
return super().get(request, *args, **kwargs)
Urls.py:
path('dashboard/listpost/search/', SearchView.as_view(), name="search")
ListPost.html:
{% extends "admin/layout.html" %}
{% block title %}
<title>Post List</title>
{% endblock title %}
{% block content %}
<form action="{% url 'search' %}" method="GET">
<input type="text" placeholder="Cerca" name="search"> <button>Cerca</button>
</form>
<div class="postlist">
<div class="cards"> <!-- Card Container -->
{% for post in object_list %}
<div class="card"> <!-- Single Card -->
{% if post.image %}
<img src="{{post.image.url}}" alt="">
{% endif %}
<h3>{{ post.title }}</h3>
<p>
{{ post.category }}
{{ post.author }}
<data class="data"> {{ post.date|date:'d-m-Y' }} </data>
</p>
<p class="desc-list">{{ post.desc|truncatewords:10 }}</p>
edit
delate
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
Search.html
{% extends "admin/layout.html" %}
{% block title %}
<title>Search</title>
{% endblock title %}
{% block content %}
{% if query %}
{{Query}}
{% else %}
<p>Nope</p>
{% endif %}
{% endblock content %}
Your are trying to display the variable query, Query (two different variables since the template language is case sensitive).
Your do not pass any of those two variables in the template context.
I don't see any query nor Query variable in your view.
It seems that your want to show the results variable, so I will assume this.
Your need to send the results from your queryset in the template results.
The get_context_data method ContextMixin (one of the TemplateView derived classes) is useful for this.
class SearchView(TemplateView):
model = Post
template_name = "admin/search.html"
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Post.objects.filter(text__icontains=q, desc__icontains = q, title__icontains = q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
"""Add context to the template"""
return super().get_context_data(results=results, **kwargs)
And in your template:
{% extends "admin/layout.html" %}
{% block title %}
<title>Search</title>
{% endblock title %}
{% block content %}
{% if results.exists %}
{% for result in results %}
{{ result }}
{% endfor %}
{% else %}
<p>Nope</p>
{% endif %}
{% endblock content %}
I try to rebuild this example:
https://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/
I have a model "Product" and a model "Order". Order has a foreignkey to "product". So for 1 Product I have N Orders
In my template I have to display a lot of information so I would like to avoid to do "for order in Product.order_set.all()" in my template
In my template, if I write :
{{ object_list.1.related_items }}
everything is fine and I get what I want
but if I write:
{% for i in object_list %}
{{ object_list.i.related_items }}
{% endfor %}
I don't get a result.
Can somebody tell me how I solve this problem?
My object_list is nearly the same as in the above example:
products = Product.objects.all()
i = 0
qs = Product.objects.all()
obj_dict = dict([(obj.id, obj) for obj in qs])
objects = Order.objects.filter(producttyp__in=qs)
relation_dict = {}
for obj in objects:
relation_dict.setdefault(obj.producttyp_id, []).append(obj)
for id, related_items in relation_dict.items():
obj_dict[id].related_items = related_items
def get(self,request,*args,**kwargs):
context = {'object_list':self.obj_dict}
return render(request,self.template_name,context)
the only change i did is from
obj_dict[id]._related_items to obj_dict[id].related_items because of the not allowed underscore?!
How do I print the list in my template like:
- Product A
- Order 1
- Order 2
- Order 5
- Product B
- Order 3
- Order 6
best regards
That is logical, since here Django interprets i not as the variable, but as the an identifier, so it aims to access object_list.i, or object_list['i'], not object_list.1 for example.
You however do not need i here, you can just access the related_items of the object, like:
{% for object in object_list %}
{{ object.related_items }}
{% endfor %}
If related_items is, as the name suggests, a collection as well, we can iterate over these items as well:
{% for object in object_list %}
{% for subitem in object.related_items %}
{{ subitem }}
{% endfor %}
{% endfor %}
for a dictionary, we can access the .values, like:
{% for object in object_dict.values %}
{{ object.related_items }}
{% endfor %}
EDIT: as for the specific case of the listview. You can use .prefetch_related to fetch all the relations with one extra query:
class MyListView(ListView):
queryset = Product.objects.prefetch_related('order_set')
template = 'my_template.html'
In the template you can then render this like:
<ul>
{% for product in object_list %}
<li>{{ product }}</li>
<ul>
{% for order in product.order_set %}
<li>{{ order }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
I would like to fetch the names of the speakers in the template. I marked it with xxxx. How can I do this? Thank you so much for helping out. My files:
models.py
class City(models.Model):
name = models.CharField(max_length=100)
class Speaker(models.Model):
name = models.CharField(max_length=100)
url = models.URLField(max_length=100)
city = models.ManyToManyField(City, blank=True)
views.py
def home(request):
cities = City.objects.all().exclude(speaker__isnull=True)
return render(request, "index.html", {"cities":cities})
index.html
{% for i in cities %}
{{ i.name }},xxx{{ i.speaker.name }}xxx<br>
{% endfor %}
You can access the speakers for each city as speaker_set:
{% for cit in cities %}
{{ cit.name }}
{% for spkr in cit.speaker_set.all %}
{{ spkr.name }}
<br>
{% endfor %}
{% endfor %}
I'm trying to run a search on a model that has a many to many field, and I want to filter the search using this field.
here is my current code:
search_indexes.py
class ListingInex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
business_name = indexes.CharField(model_attr='business_name')
category = indexes.MultiValueField(indexed=True, stored=True)
city = indexes.CharField(model_attr='city')
neighborhood= indexes.CharField(model_attr='neighborhood')
state = indexes.CharField(model_attr='state')
address = indexes.CharField(model_attr='address')
zip_code = indexes.CharField(model_attr='zip_code')
phone_number = indexes.CharField(model_attr='phone_number')
def get_model(self):
return listing
def index_queryset(self, using=None):
return self.get_model().objects.all()
def prepare_category(self, obj):
return [category.name for category in obj.category_set.all()]
listing_text.txt
{{ object.business_name }}
{{ object.state }}
{{object.city}}
{{object.zip_code}}
{{object.phone_number}}
{{object.neighborhood}}
{% for category in obj.category.all %}
{{ category.name }}
{% endfor %}
I'm trying to do a simple search like:
search_results = SearchQuerySet().filter(category=query_text).filter
it returns an empty list. Thanks in advance.
Reading your code I think the problem is here:
{% for category in obj.category.all %}
{{ category.name }}
{% endfor %}
Category is not an object, is a MultiValueField. Maybe if you try something like:
{% for category in object.category.all %}
{{ category.name }}
{% endfor %}
object.category.all instead of obj.category.all. I'm not sure the solution is this, but I'm pretty sure the error could be in this 3 lines.