Django Filter Queryset Model - django

How can I filter my table to only show the quotes from a project.
In order to display all quotes, I am using {% for quote in quotes.all %}
Now, I would like to display quote relative to a site. Which means when selecting my site_id, I`ll be able to only see the quote relative to this site_id. I could write something like
{% for quote in quotes.all %}
{% if quote chantier.id %}
{% endif %}
{% endfor %}
but this is wrong.
Here is my model for quote:
models.py
class Quote(models.Model):
name = models.CharField(max_length=30)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
How can I display all quotes from this site?
Many Thanks,

You can make a url path that contains the site_id:
# app_name/urls.py
from django.urls import path
from app_name import views
urlpatterns = [
path('site/<int:site_id>/', views.quotes_of_site, name='quotes_of_site'),
# …
]
in the view, you can then filter by site_id:
# app_name/views.py
from django.shortcuts import render
from app_name.models import Quote
def quotes_of_site(request, site_id):
quotes = Quote.objects.filter(site_id=site_id)
return render(request, 'name_of_template.html', {'quotes': quotes})
and then iterate over this QuerySet:
{% for quote in quotes %}
…
{% endfor %}

Related

Django 2.0: Get queries dynamically from search

I am new to Django framework and as a practice project I am trying to build an ecommerce website using Django. I have a class based view for my search page. I wrote the view to get the query for a particular query:
views.py
class SearchProductView(ListView):
template_name = "template.html"
queryset = Product.objects.filter(title__icontains='book')
print(queryset)
I would like to know how I can write a function to get the search queries dynamically. For e.g.: If i search book, then my queryset should contain all things about book and if I search car, then I should get all things about car.
template.html
{% extends "base.html" %}
{% block content %}
<div class='row'>
{% for object in object_list %}
<div class='col'>
{{ forloop.counter }}
{% include 'products/snippets/card.html' with instance=object %}
</div>
{% endfor %}
</div>
{% endblock %}
urls.py
from django.urls import path
from . import views
from .views import SearchProductView
app_name = 'search'
urlpatterns = [
path('', SearchProductView.as_view(), name='search_page'),
]
You need to define the get_queryset method, rather than the class-level queryset attribute. This can use your querystring parameters to filter the queryset dynamically.
You haven't shown your search form or said what your parameter is, but assuming it submits a GET parameter named q, you would do:
def get_queryset(self):
return Product.objects.filter(title__icontains=self.request.GET['q'])
Although the answer above will work I believe a better solution would be the following:
models.py
class Category(models.Model):
title = models.CharField(...)
class Product(models.Model):
...
category = models.ForeignKey(Category)
views.py
from django.db.models import Q
def get_queryset(self):
querystr = self.request.GET['q']
Product.objects.filter(
Q(title__icontains=querystr) | Q(category__title__icontains=querystr)
)

How to translate all the contents inside model queries in DJango?

i am a new to Django, i am trying to make a small blog with two different languages, i got all the translations inside my blog including the admin, but still don't know how to translate the content of my posts.
After i fetch the content using the models queries, inside my template i used to type this {% trans "SOME TEXT" %} and it works just fine, with variables that i am getting from database i am using this code:
{% blocktrans %}
{{head.title_text}}
{% endblocktrans %}
now when i type django-admin makemessages -l ru, inside django.po i can't see any new text that have been added.
Also inside my views.py i tried this:
head = Head.objects.first()
trans_h = _(u'{}'.format(head))
but nothing gets added inside django.po
Please, anyone knows how to resolve this issue ??
I think the best way to translate the content of the Post Model without using any third-party is to create for each fields you need to translate inside your models with different languages and translate them from your admin,and display them in your template when the site change the language, in Django you can translate only the text you can not translate the data from your model
Create your model Post
models.py
class Post(models.Model)
title_fr = models.CharField(max_length=200)
title_en = models.CharField(max_length=200)
content_fr = models.TextField()
content_en = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, auto_now=False)
updated_at = models.DateTimeField(auto_now_add=False, auto_now=True)
In the view you translate the text inside the variable and pass it in your template
views.py
from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse
from .models import Post
from django.utils.translation import ugettext_lazy as _
def post_view(request):
post = Post.objects.all()
# Here is you can translate the text in python
title = _("les meilleurs posts du mois")
context = {
'post':post,
'title':title
}
template = loader.get_template('index.html')
return HttpResponse(template.render(context, request))
Here the idea is once your site is translated in french for example(www.mysite.com/fr/) in your template you will get only the attributes with _fr(title_fr, content_fr) already translated in your admin and if it's in english it will be the same thing
index.html
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_available_languages as LANGUAGES %}
<h1> {{ title}}</h1>
{% if LANGUAGE_CODE|language_name_translated == 'Français' %}
{% for items in home %}
<h2>{{ items.title_fr }}</h2>
<p> {{items.content_fr}}</p>
{% endfor %}
{% if LANGUAGE_CODE|language_name_translated == 'English' %}
{% for items in home %}
<h2>{{ items.title_en }}</h2>
<p>{{items.content_en}}</p>
{% endfor %}
{% endif %}
I hope it can be helpful

Query on generic display views - Django

For the below url routing for blog app,
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from blog.models import Post
urlpatterns=[
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:25],
template_name="blog/blog.html",
)
)
]
template blog.html is,
{% extends "personal/header.html" %}
{% block content %}
{% for post in object_list %}
<h5>{{post.date|date:"Y-m-d"}} {{post.title}} </h5>
{% endfor %}
{% endblock %}
where model for blog app is defined as,
class Post(models.Model):
title = models.CharField(max_length=140)
body = models.TextField()
date = models.DateTimeField()
def __str__(self):
return self.title
MTV of blog app is structures as,
../blog
admin.py
apps.py
__init__.py
migrations
models.py
templates
tests.py
urls.py
views.p
Question:
{{post.id}} is internally created as primary key, for every row in the table, but,
What does /blog/{{post.id}} mean in the template(blog.html)?
When you want to go to a particular blog, you need to have a link to that. That's what /blog/{{post.id}} does as a link.
so /blog/1 gives you the first blog. Only that you have to define the url pattern, the view and the template for that.
url(r'^(?P<id>[^/]+)/$', views.get_blog, name='one_blog'),
Then in views:
def get_blog(request, id):
blog = Blogs.objects.get(id=id)
return render(request, 'blogs/one_blog.html', locals())
And then in templates folder, create a 'blogs/one_blog.html' file. Simplest example being:
{% extends "personal/header.html" %}
{% block content %}
<h5>{{blog.title}}</h5>
{{blog.body}}
{% endblock %}
Just make sure that you understand the folder structure for templates.
it's just a prefix /prefix/id/. It is also possible /article/1... it doesn't matter
urls.py
urlPatterns=[
url(r'^$', ListView.as_view(
model=Post,
template_name="blog/blog_list.html",
)
)
url(r'blog/(?P<pk>[\w-]+)/$', DetailView.as_view(
model=Post,
template_name="blog/blog_detail.html",
)
)
]

ListView for Django not Working but function based view is working

When I am using function based view using the following code:
from django.views import View
from django.views.generic import TemplateView, ListView
from .models import Restaurant
def restaurant_listview(request):
template = 'restaurants/restaurants_list.html'
context = {
"queryset" : Restaurant.objects.order_by('-updated')
}
return render (request, template, context)
it is working with the url file kept as follows:
from django.conf.urls import url
from django.contrib import admin
from restaurants import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^restaurants/$', views.restaurant_listview),
]
But when I am trying to do the same thing with class based views it is not working only the following portion doesn't seem to work:
<ul>
{% for obj in queryset %}
<li>{{obj.name}}, {{obj.location}}, {{obj.category}}, {{obj.timestamp}}</li>
{% endfor %}
</ul>
the following part works fine:
{% extends 'base.html' %}
{% block title %}
Restaurants List {{ block.super }}
{% endblock %}
{% block content %}
<h1>Restaurants</h1>
for class based view my views.py is:
class RestaurantListView(ListView):
queryset = Restaurant.objects.all()
template_name = 'restaurants/restaurants_list.html'
and urls.py is:
url(r'^restaurants$', RestaurantListView.as_view(), name='Home')
P.S. I am following this guide : https://www.youtube.com/watch?v=yDv5FIAeyoY&t=25471s
For a list view, you should change the template to:
{% for obj in restaurant_list %}
Or, if you really want to use the variable queryset in the template, then set context_object_name.
class RestaurantListView(ListView):
queryset = Restaurant.objects.all()
template_name = 'restaurants/restaurants_list.html'
context_object_name = 'queryset'

Simple search exercise from DjangoBook Chapter 7

It seems to be working now, all I changed was chartext to charfield in my models. Why won't it search in chartext? Was that the fix?
I am having some issue with section 7 of djangobook, where we show the results of our book search. I am not using books, but I dont know what I am doing wrong.
Note: The search term 'q' is being passed through properly, it just wont show results. The template does show up though. I was going to just skip it, but I really am starting to wonder what else I could be doing wrong?
I am following from : http://djangobook.com/en/2.0/chapter07/ here is my code
urls.py
from django.conf.urls.defaults import patterns, include, url
from EM.catalog import views
urlpatterns = patterns('',
(r'^search-form/$', views.search_form),
(r'^search/$', views.search),
views.py
from django.template import loader, Context
from django.shortcuts import render_to_response
from django.http import HttpResponse
from EM.catalog.models import em_tank
def search_form(request):
return render_to_response('search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
tanknotes = em_tank.objects.filter(em_tank_notes__icontains=q)
return render_to_response('search-results.html', {'tanknotes': tanknotes, 'query': q})
else:
return HttpResponse("Please input a search term")
search-results.html
<p>You searched for: <strong>{{ query }}</strong></p>
{% if tanknotes %}
<p>Found {{ tanknotes|length }} result{{ tanknotes|pluralize }}.</p>
<ul>
{% for em_tank_notes in tanknotes %}
<li>{{ em_tank.em_tank_notes }}</li>
{% endfor %}
</ul>
{% else %}
<p>No tanks matched your search criteria.</p>
{% endif %}
models
from django.db import models
class em_tank(models.Model):
em_tank_date_acquired = models.DateField()
em_tank_notes = models.CharField(max_length=150, verbose_name='Notes', blank=True)