Loop in django with 2 parameter [duplicate] - html

This question already has answers here:
is there a way to loop over two lists simultaneously in django?
(6 answers)
Closed 6 years ago.
I am new to Django, I have passed two list(rawmaterial and food) to my template, and then I want to have a loop like this :(it is the logic of my aim, the syntax is not correct)
for(i=0;i<food.length;i++)
<div ,id="menuFood>
<h4> food.name(i)</h4>
<h4> rawmaterial.name(i)</h4>
</div>
but when i searched, i can find only loop like this:
{% for o in some_list %}
{% endfor %}
so with this syntax , I can't understand how to create that loop. I think only nested loop can make by this syntax..
here is my view code :
def foods(request):
food = Food.objects.all()
raw = [];
.
.
.
raw.append(warehouse)
return render(request, 'polls/foods.html', {'food': food,'rawmaterial': raw})

You can't do index on django template, but you could just put 2 lists together in your views.py using zip function:
food = Food.objects.all()
raw = []
# ...
raw.append(warehouse)
result = zip(food, raw)
return render(request, 'polls/foods.html', {'result': result})
Then in your template:
{% for food, raw in result %}
<h4>{{ food }}</h4>
<h4>{{ raw }}</h4>
{% endfor %}
By the way, you seems to come from java/c++ background because in python people never do:
for(i=0; i<food.length; i++)
print food[i]
instead, we do:
for i in food:
print i
Django template is adopting the similar syntax, it makes writing a loop a lot easier.

Related

Django How to make the condition correct on an HTML page - search bar

I try to do a search engine if the word in my DB thah I created then display the word on the HTML page and if not then nothing.. I did it right in VIEW but I can not apply it on the HTML page I searched the internet and did not find an answer I'm sure I fall for something stupid.
This is the view
def Search_word(request):
search = request.POST.get("search") #Grab the search item
return render(request,"search_page.html", {"search":search})
this is the html:
{%for i in Word.English_word%}
{%if search in Word.English_word%}
{{search}}
{%endif%}
{%endfor%}
and the urls:
path("Search_page",views.Search_word ,name="Search-page"),
models:
class Words(models.Model):
English_word = models.CharField(max_length=30)
Hebrew_word = models.CharField(max_length=30)
How_To_Remember = models.CharField(max_length=40)
Name = models.CharField(max_length=20)
pub_date = models.DateTimeField()
The problem is that even if the word is valid it does not show me anything ..
You should implement the filtering logic in the view, not in the template. Templates are for rendering logic, not business logic. Furthermore one should filter with the database, since databases are designed to do this.
The view thus looks like:
def Search_word(request):
search = request.POST.get('search')
items = Word.objects.filter(English_word__contains=search)
return render(
request,
'search_page.html',
{'search': search, 'items': items}
)
and then in the template we render this with:
{% for item in items %}
{{ item.English_word }}: {{ item.Hebrew_word }} <br>
{% endfor %}
You can use as lookup __contains to check if the English_word has a substring that is equal to search, with __icontains you check case-insensitive, with __iexact you look for Words that match search case-insensitive, and finally you can filter with Engish_word=search for an exact match.

Need help creating search view and how to apply in the HTML page from DB that I created - Django

I am building a website with DJANGO where people put words and association how to remember the word.
I built the part of inserting the word.
I am now stuck in the part of implementing the word search and extracting the information from the DB.
def Search_word(request):
if request.method == "POST":
search = request.POST["search"]
word = Words.objects.filter(English_word__contains = search)
return render(request,"search_page.html",{word:word , search:search})
else:
return render(request,"search_page.html",{})
{% if search %}
<h1> You searched for {{search}}</h1>
{% for Words in search %}
{{Words.English_word}}
{{ Words.Hebrew_word }}
{{ Words.How_To_Remember}}
{% endfor %}
{% else %}
<h1> Hey! You Forgot To Search </h1>
{% endif %}
if you want to search only in one field, Django supports search which is much better and more accurate than contains
words = Words.objects.filter(English_word__search = search_term)
but if you like to have some sort of search engine-like functionality you can use PostgreSQL with Django's full text search feature
in model.py add these commands
from django.contrib.postgres.search import SearchVector
in your model manger:
def full_search(self, search_term):
return self.annotate(
search=SearchVector('English_word') +
SearchVector('blog__tagline')).filter(search=seach_term)
this method will remove <in/at/is/the/...> other English words and only search with word-to-vector algorithms
if you have to work with ranking the search results:
from django.contrib.postgres.search import SearchQuery, SearchRank,SearchVector
vector = SearchVector('english_word')
query = SearchQuery(search_term)
Word.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank')
this will annotate the results based on their likelihood to search term.
by the way It's best practice to use Model Mangers and avoid doing ORM stuff in views.
Django Docs on search:
https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/search/

How to integrate jinja module inside PyGears

I created jinja module as example, which looks like this
{% from 'snippet.j2' import module with context %}
{% call module() %}
logic [$size(din.data)-1 : 0] res;
assign res = din.data * din.data;
{% if params['half'] %}
assign dout.data = res / 2;
{% else %}
assign dout.data = res;
{% endif %}
assign din.ready = dout.ready;
assign dout.valid = din.valid;
{% endcall %}
How should I use this module inside PyGears?
Okay, I think this should work.
If I understood correctly you are trying to create a Jinja template for a module that will multiply with 1/2 (in other words divide by two). First of all, make sure your Jinja file and module are named the same (this is a must so PyGears would know which Jinja template to use).
Having all this in mind let's say our module name is mulh
Python file would be something like this:
from pygears import gear, Intf, reg
from pygears.typing import Uint
from pygears.hdl import hdlgen
#gear
def mulh(din: Uint,*,half=False)->b'din*din':
    pass
mulh(Intf(Uint[8]))
hdlgen('/mulh', outdir='.')
This code will call your Jinja file and the HDL output would look like something like this:
module mulh
(
    input logic clk,
    input logic rst,
    dti.consumer din, // u8 (8)
    dti.producer dout // u16 (16)
);
    typedef logic [7:0] din_t; // u8
    typedef logic [15:0] dout_t; // u16
    din_t din_s;
    dout_t dout_s;
    assign din_s = din.data;
    assign dout.data = dout_s;
    logic [$size(din.data)-1 : 0] res;
    assign res          = din.data * din.data;
    assign dout.data    = res;
assign din.ready    = dout.ready;
    assign dout.valid   = din.valid;
endmodule
To make it easier to picture all of this I made this picture bellow

Django Search Page with Query Pagination

Hello i have implemented a simple search form and search view to show search result. Now i want to paginate them. But there is a problem with the page in the url. My search url looks like ../search?q=Bla
Now if i try to add pagination like: ../search?q=Bla?page=2 (at least thats how i understand it would work) it takes the whole string after q= to my database filter. I took a look at how stackoverflow handles searching and pagination and found out using '&' here is the view code:
def search(request):
# get query search parameters
page = request.GET.get('page', 1)
query = request.GET.get('q', '')
# query none or empty
if query is None or query == '':
return redirect('home')
# query valid
else:
# icontains make sure to ignore character sensitivity
post_list = Post.objects.filter(title__icontains=query)
paginator = Paginator(post_list, 5)
try:
posts_l = paginator.page(page)
except PageNotAnInteger:
posts_l = paginator.page(1)
except EmptyPage:
posts_l = paginator.page(paginator.num_pages)
return render(request, 'search.html', {'post_list': posts_l, 'query': query})
and here the HTML Snippet:
{% if post_list.paginator.num_pages > 1 %}
<div class="pagination">
<span class="step-links mb-5 mx-auto">
{% if post_list.has_previous %}
<a class="mr-3" href="?page={{ post_list.previous_page_number }}&q={{ query }}">zurück</a>
{% endif %}
<span>Seite {{ post_list.number }} von {{ post_list.paginator.num_pages }}</span>
{% if post_list.has_next %}
<a class="ml-3" href="?page={{ post_list.next_page_number }}&q={{ query }}">nächste</a>
{% endif %}
</span>
</div>
{% endif %}
So now the url is build like search?q=Test for the first page. And for the other pages (which suprisingly works) is search?page=2&q=Test. Now im happy it works but i dont quite how just adding &q={{ query }} solved my problem. Is this some kind of universal RFC? I dont quite understand since i was just checking out how this side does it. implemented it and works?
A query string [wiki] is the part after the question mark (?) of a URL. It is a string that consists out of a sequence of key-value pairs separated by an ampersand (&). The key and the value are separated by the equals sign (=). Both the key and the value are percent-encoded [wiki]. So as you found out:
page=2&q=Test
is a querystring that contains two key-value pairs: page maps to 2 and q to test.
The code is however not entirely "safe". If the query itself contains an ampersand &, etc. then this can result in an incorrect query. You should make use of the |urlencode template filter [Django-doc] to percentage encode the value:
<a class="ml-3" href="?page={{ post_list.next_page_number }}&q={{ query|urlencode }}">nächste</a>

Align dynamic number of images django templates

I have a django template that gets a set of images. The number of images varies. I want to align it in the template file, like 3 images per line. Normal displaying of the image does not align it. creating a
<div class="col-md-4">
</div>
for each image misformats after 3 images. How do I acquire this, either using django itself, or in bootstrap?
If I understand correctly you need to close your row after 3 objects.
To do this you should take a look at forloop.counter template tag and divisibleby filter in Django documentation about built-in template tags.
It seems that you want to split a list into equally sized chunks in django templates.
The following snippet would help.
Templatetag code:
from django import template
register = template.Library()
#register.filter(name='chunks')
def chunks(iterable, chunk_size):
if not hasattr(iterable, '__iter__'):
# can't use "return" and "yield" in the same function
yield iterable
else:
i = 0
chunk = []
for item in iterable:
chunk.append(item)
i += 1
if not i % chunk_size:
yield chunk
chunk = []
if chunk:
# some items will remain which haven't been yielded yet,
# unless len(iterable) is divisible by chunk_size
yield chunk
Template code:
{% for chunk in images|chunks:3 %}
<div class="row">
{% for image in chunk %}
<div class="col-md-4">
{{image}}
</div>
{% endfor %}
</div>
{% endfor %}