convert string value to integer in Django template - django

In home.html
<div class="container">
<div class="row">
<div class="col-md-6">
<h3>Select products:</h3>
<form id="selectProduct" role="search" method="get" action="{% url 'home' %}">
<select name="parameters" data-placeholder="Choose products" class="chosen-select" multiple tabindex="4">
{% for p in productnames %}
{% if k == p %}
<option value="{{ p.productnames }}" selected> {{ p.productnames }} </option>
{% else%}
<option value="{{ p.id }}"> {{ p.productnames }} </option>
{% endif %}
{% endfor %}
</select><br/>
<label for="submit"></label><button id="submit" type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="row"></div><br />
<h3> Distribution of sales in the products:</h3>
</div>
</div>
{% for p in productList %}
{% for pin in productnames %}
<p>{{pin.id}} {{p}}</p>
{% if p == pin.id %}
<p>exists</p>
{% else %}
<p>not exist</p>
{% endif %}
{% endfor %}
{% endfor %}
<p>{{ productList }}</p>
in this html file 'p' always returns a string value for ex: it returns like '10' instead of 10. all i want is to convent this '10' to 10 or convert returned other p_in value to 10 to '10'.
in views.py
def productList(request):
if request.method == 'GET':
p = request.GET.get('parameters')
print(p)
#k = request.GET('parameters[]')
productnames = Products.objects.all()
context = {
'productList': p, 'productnames': productnames,
}
return render(request, 'home.html', context)
I tried to convert the values of the p in product list to integer. because it dosen't mactch the format with pin.id

You filter the queryset in the template using if-else which is not ideal. Instead you should perform this filtering in the view itself. Also your parameters is a select tag which may have multiple selected values yet you use .get('parameters') which will only give you one value instead you should use the getlist method [Django docs] of the QueryDict:
def productList(request):
if request.method == 'GET': # Do you even need to check this? You appear to only use a GET request...
p = request.GET.getlist('parameters')
productnames = Products.objects.all()
filtered_products = Products.objects.filter(pk__in=p)
context = {
'productList': p, 'productnames': productnames, 'filtered_products': filtered_products
}
return render(request, 'home.html', context)
In the template your loop would simply become:
{% for product in filtered_products %}
{{ product.productnames }}
{% endfor %}
Note: You should use a form class instead of manually making a form. See Building a form in
Django.
Also a models name should be singular hence instead of
Products you should name it Product. In general in
your code you also break various naming conventions in Python, I would
suggest you to look at PEP 8 -- Style Guide for Python
Code

In views.py
def productList(request):
if request.method == 'GET':
p = request.GET.getlist('parameters')
print(p)
#k = request.GET('parameters[]')
productnames = Products.objects.all()
context = {
'productList': p, 'productnames': productnames,
}
# --- logic later for chart ------
return render(request, 'home.html', context)
In home.html
<div class="container">
<div class="row">
<div class="col-md-6">
<h3>Select products:</h3>
<form id="selectProduct" role="search" method="get" action="{% url 'home' %}">
<select name="parameters" data-placeholder="Choose products" class="chosen-select" multiple tabindex="4">
{% for p in productnames %}
{% if k == p %}
<option value="{{ p.productnames }}" selected> {{ p.productnames }} </option>
{% else%}
<option value="{{ p.id }}"> {{ p.productnames }} </option>
{% endif %}
{% endfor %}
</select><br/>
<label for="submit"></label><button id="submit" type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="row"></div><br />
<h3> Distribution of sales in the products:</h3>
</div>
</div>
{% for p in productList %}
{% for pin in productnames %}
<p>{{pin.id|stringformat:"s"}} {{p}}</p>
{% if p == pin.id|stringformat:"s" %}
<p>exists</p>
{% else %}
<p>not exist</p>
{% endif %}
{% endfor %}
{% endfor %}
<p>{{ productList }}</p>
Note {{value|stringformat:"s"}} can be used to convert integer value to string value

Related

My django form is not working when i iterate through it using for loop

Basically if I tried to use this code
{% for field in form %}
<div class="input">
<label for="" class="labelinput">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
the form data wont make it pass is_valid().But it renders out the form fine. and if I use this code
<form action="" method="post"> {% csrf_token %}
{{form}}
<input type="submit" value="">
it worked perfectly fine. How do I get the first code to work because I want to add classes between the label and the input field
and here's my view
def booklist_view(request):
bkff = BookListForm()
if request.method == 'POST':
bkff = BookListForm(request.POST)
if bkff.is_valid():
bkff.save()
bkff = BookListForm()
context = {
'form': bkff,
}
return render(request, 'booklist1st/booklist.html', context)
Please try this.
views.py
def booklist_view(request):
form = BookListForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
context = {'form': form }
return render(request, 'booklist1st/booklist.html', context)
Here we render field according according to field type(hidden_fields,visible_fields).
html template:
<form method="post">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="input">
{{field.label}}
{{field}}
</div>
{% endif %}
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
You need to specify each field relate data like for=, id=, etc. To have maximum control over how your form is rendered, specify each field and control its style, for example, as we can't see your Form definition, this is an example on how it would be for a title field:
<form method="post">{% csrf_token %}
{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{{ form.non_field_errors }}
{{ form.title.errors }}
<label for="{{ form.title.id_for_label }}">Title</label>
{{ form.title }}
{% if form.title.help_text %}
<small id="titleHelp">{{ form.title.help_text|safe }}</small>
{% endif %}
</div>
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
<form method="post">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="input">
<label for="" class="label">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<input class="btn btn-primary" type="submit" name="add_book" value="Save and add book" />
</form>
View.py
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def booklist_view(request):
bkff = BookListForm()
if request.method == 'POST':
bkff = BookListForm(request.POST)
if bkff.is_valid():
bkff.save()
context = {
'form': bkff,
}
return render(request, 'booklist1st/booklist.html', context)

Get Django search query right

Im currently facing a problem since a couple of days for now. I simply want to implement a search view into my Django app. But when i try to search something on my App i get the following error:
init() takes 1 positional argument but 2 were given__init__() takes
In the end i want that my Query is a combination of category and searchword. So that the user can filter specific categories (Just like Amazon.com searchfield) e.g.: http://127.0.0.1:8000/search/?category=1&q=hallo
base.html
...
<div class="globalsearch">
<form id="searchform" action="{% url 'search' %}" method="get" accept-charset="utf-8">
<label for="{{ categorysearch_form.category.id_for_label }}">In category: </label> {{ categorysearch_form.category }}
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search for ...">
<button class="searchbutton" type="submit">
<i class="fa fa-search"></i>
</button>
</form>
</div>
</div>
...
categorysearch_form is a dropdown selector that gets his ID from the Database.
views.py
...
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
from django.views.generic import ListView
class globalsearch(ListView):
"""
Display a Post List page filtered by the search query.
"""
model = Post
paginate_by = 10
def get_queryset(self):
qs = Post.objects.published()
keywords = self.request.GET.get('q')
if keywords:
query = SearchQuery(keywords)
title_vector = SearchVector('title', weight='A')
content_vector = SearchVector('content', weight='B')
tag_vector = SearchVector('tag', weight='C')
vectors = title_vector + content_vector + tag_vector
qs = qs.annotate(search=vectors).filter(search=query)
qs = qs.annotate(rank=SearchRank(vectors, query)).order_by('-rank')
return qs
...
urls.py
...
url(r'^search/$', views.globalsearch.as_view(), name='search'),
...
Search.html results are getting displayd here:
{% extends 'quickblog/base.html' %}
{% block content %}
{% for post in object_list %}
<div class="post">
<h1><u>{{ post.title }}</u></h1>
<p>{{ post.content|linebreaksbr }}</p>
<div class="date">
<a>Published by: {{ post.author }}</a><br>
<a>Published at: {{ post.published_date }}</a><br>
<a>Category: {{ post.category }}</a><br>
<a>Tag(s): {{ post.tag }}</a>
</div>
</div>
{% endfor %}
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
{% endblock %}
Project: https://github.com/rsmvdl/quickblog
Since globalsearch is class based view it should be globalsearch.as_view() in your urls:
url(r'^search/$', views.globalsearch.as_view(), name='search'),

Django formset not rendering with django-widget-tweaks

I am getting the error 'LoginForm' object has no attribute 'as_widget' whenever I use formset. I really do not know what is the problem as the forms renders properly with normal Django forms. I am trying to see what characteristics in the formset is giving this problem with django-widget-tweaks, but up until now it is hard to figure out. I am getting the error at {% render_field field class="form-control" placeholder=field.label %} in the HTML code.
forms.py:
class LoginForm(ModelForm):
user_login = forms.HiddenInput()
prefix = 'prefix_login'
class Meta:
model = Usermie
fields = ['email', 'password']
widgets = {'password': forms.PasswordInput(),
'email': forms.EmailInput()}
views.py
def manage_articles(request):
article_formset = formset_factory(LoginForm)
book_formset = formset_factory(SignUpForm)
if request.method == 'POST':
if 'login' in request.POST:
login = article_formset(request.POST, request.FILES, prefix='login')
if login.is_valid():
email = request.POST.get('prefix_login-email', '')
password = request.POST.get('prefix_login-password', '')
# Return a user_obj object if the username and password are valid
# otherwise it will return null, the null variable is called None in python
user_obj = auth.authenticate(email=email, password=password)
# return HttpResponse("inside form if condition")
if user_obj is not None:
if user_obj.is_active:
login_usermie(request, user_obj)
return HttpResponseRedirect('/home/')
else:
# pass
return HttpResponse("Your account is inactive.")
elif 'signup' in request.POST:
signup = book_formset(request.POST, request.FILES)
if signup.is_valid():
pass
else:
login = article_formset
signup = book_formset
return render(request, 'usermie/formtest.html', {
'login': login,
'signup': signup,
})
HTML:
<div class="navbar navbar-default nav-links navbar-static-top page-nav">
<div class="container">
<a class="mini-navbar navbar-brand" href="/">
<img src="http://i.imgur.com/GAQSCtB.png" width="25"
alt="Driven Car Sales Logo"
class="img-rounded logo-nav mini-navbar" />
</a>
<ul class="nav navbar-nav nav-form-out pull-right">
<li>
<form class="navbar-form navbar-form-out login" action="" method="POST">
{% csrf_token %}
{% load widget_tweaks %}
{% for field in login %}
{% if login.errors %}
<div class="form-group">
<label class="sr-only" for="{{ field.auto_id }}">{{ field.label }}</label>
{% render_field field class="form-control" placeholder=field.label %}
{% if field == login.password %}
{% for hidden in field.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
<div class="help-block with-errors">{{ field.errors }}</div>
</div>
{% else %}
<div class="form-group">
<label class="sr-only" for="{{ field.auto_id }}">{{ field.label }}</label>
{% render_field field class="form-control" placeholder=field.label %}
{% if field == login.password %}
{% for hidden in field.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
</div>
{% endif %}
{% endfor %}
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
<button type="submit" name="action" value="login" class="btn btn-default">Sign in</button>
</form>
</li>
</ul>
</div>
<form class="signup" method="POST" action="">
{% csrf_token %}
{{ signup.as_p }}
<button name='action' value='signup' type="submit">Sign up</button>
</form>
login variable in template is a formset. So when you do following:
{% for field in login %}
{% render_field field class="form-control" placeholder=field.label %}
{% endfor %}
you have form as field value and not a field.
Try do this:
{% for form in login %}
{% for field in form %}
{% render_field field class="form-control" placeholder=field.label %}
{% endfor %}
{% endfor %}

How to store form data in form pagination using session?

I'm working on a quiz. The quiz has multiple questions - forms. Since there may be many questions, I've created a pagination for these forms. Everything seems to work correctly but only the data from forms on last page are sent to server.
How to hold the data from previous pages so I can send all forms then to server?
I'm considering using session but can't figure out how to make it work. As you can see, all questions are in one form with method post. But pagination are GET methods.
def take_quiz(request,id):
if request.method == 'POST':
quiz = get_object_or_404(models.LanguageQuiz, pk=id)
sitting = get_object_or_404(models.Sitting, quiz=quiz, user=request.user)
for k,v in request.POST.iteritems():
if 'choice-for' in k:
q = Question.objects.get(pk=k.split('-')[-1])
choice = Choice.objects.get(pk=v)
sitting_question = get_object_or_404(SittingQuestion,sitting=sitting,question=q)
sitting_question.answer = choice
sitting_question.save()
correct_answers = len([x for x in sitting.sitting_questions.all() if x.answer.correct])
result = float(correct_answers)/sitting.sitting_questions.all().count() * 100
return render(request,'quiz/result.html',context={'result':result,
'level':level,
'quiz':quiz})
if request.method == 'GET':
with transaction.atomic():
quiz = get_object_or_404(models.LanguageQuiz, pk=id)
if models.Sitting.objects.filter(quiz=quiz, user=request.user).exists():
sitting = get_object_or_404(models.Sitting, quiz=quiz, user=request.user)
check_expired_sitting(sitting)
sitting.delete()
sitting = models.Sitting.objects.create(quiz=quiz, user=request.user)
sitting.load_questions()
questions = [x.question for x in sitting.sitting_questions.all()]
paginator = Paginator(questions,2)
page_num = request.GET.get('page',1)
page = paginator.page(page_num)
context = {'page':page,
'quiz':quiz}
return render(request,'quiz/quiz.html',context=context)
TEMPLATE
{% extends 'base.html' %}
{% block content %}
<h1>{{ quiz.name }}</h1>
<br><br><br>
<form action="" method="post">{% csrf_token %}
{% for question in page.object_list %}
<div class="question">
<h3>{{ question.text }}</h3>
<div class="choices">
{% for choice in question.get_choices_list %}
<input type="radio" name="choice-for-question-{{ question.id }}"
id="choice-{{ question.id }}-{{ forloop.counter }}" value="{{ choice.id }}"/>
<label for="choice-{{ question.id }}-{{ forloop.counter }}">{{ choice.text }}</label><br/>
{% endfor %}
</div>
</div>
{% endfor %}
{% if not page.has_next %}
<button class='accordion' type="submit">Submit Quiz</button>
{% endif %}
</form>
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}

modal form embedded in html does not work in django

I'm making an application for food recipes and am trying to do the same html in the recipe and include comments in a modal window, the problem is that when I give I submit template fails and does not save the comment on the data base
urls.py
urlpatterns = patterns('recetas.apps.menus.views',
url(r'^recetas/$','recetas_view',name='vista_recetas'),
url(r'^reporte/$','reporte_receta',name='receta_reporte'),
url(r'^receta/(?P<id_receta>\d+)$','detalle_receta', name='vista_detalle'),
)
The html code that calls this url
<td><a href='/receta/{{ receta.id }}'>{{ receta.titulo }}</a></td>
views.py
def detalle_receta(request, id_receta):
dato = get_object_or_404(Receta, pk=id_receta)
comentarios = Comentario.objects.filter(receta=dato)
if request.POST:
if request.POST.get('cancel', id_receta):
return HttpResponseRedirect('/receta/{0}'.format(id_receta))
form = ComentarioForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/receta/{0}'.format(id_receta))
else:
form = ComentarioForm(initial={'receta': id_receta})
cxt = {'receta':dato,'comentarios':comentarios,'form':form}
return render_to_response('menus/receta.html', cxt, context_instance=RequestContext(request))
receta.html
{% extends 'base.html' %}
{% block titulo %}{{ receta.titulo }}{% endblock titulo %}
{% block estatico %}
<link rel='stylesheet' href='{{ STATIC_URL }}css/receta.css' type='text/css'>
<link rel='stylesheet' href='{{ STATIC_URL }}css/modal.css' type='text/css'>
<script type='text/javascript'>
function despliegaModal(valor) {
var elem = document.getElementById("bgVentanaModal");
elem.style.visibility = valor;
}
</script>
{% endblock estatico %}
{% block contenido %}
<div id="bgVentanaModal">
<div id="ventanaModal">
<form action="/receta/{{ receta.id_receta }}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Grabar">
<input name="cancel" type="submit" value="Cancelar">
</form>
</div>
</div>
<div id=receta>
<div id="nombre_receta">
<h1>{{receta.titulo|title}}</h1>
<hr>
</div>
<div id='ingredientes'>
<h2>Ingredientes</h2>
<p>{{ receta.ingredientes }}</p>
</div>
<div id='imagen'>
<img src='{{MEDIA_URL}}{{receta.imagen}}' width="480" height="300" >
</div>
<div id='preparacion'>
<h2>Preparación</h2>
<p>{{ receta.preparacion }}</p>
</div>
<div id='comentarios'>
<h2>Comentarios</h2>
{% for item in comentarios %}
<p>{{ item.texto}}</p>
{% empty %}
<p>Sin Comentarios registrados</p>
{% endfor %}
{% if user.is_authenticated %}
Agregue su comentario
{% endif %}
</div>
<div id="pie">
<hr>
<p>Receta Registrada el {{ receta.tiempo_registro|date:'SHORT_DATETIME_FORMAT' }} por {{ receta.usuario }}</p>
</div>
</div>
{% endblock contenido %}
everything works until I give the cancel key, does not validate the POST.
I believe the problem is in your view.py. Specifically in this part:
if request.POST.get('cancel', id_receta):
return HttpResponseRedirect('/receta/{0}'.format(id_receta))
That if will never result in a False value and, hence, your comment will never be saved. This has to do with how the dict.get function works:
get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.
So, if you click Grabar you'll get the default value (id_receta). Try the following instead:
if request.POST.get('cancel'): # Default to None
return HttpResponseRedirect('/receta/{0}'.format(id_receta))
A workaround would be just using a button with some JavaScript to redirect when you click Cancelar in your template:
views.py
def detalle_receta(request, id_receta):
dato = get_object_or_404(Receta, pk=id_receta)
comentarios = Comentario.objects.filter(receta=dato)
if request.POST:
# if request.POST.get('cancel', id_receta):
# return HttpResponseRedirect('/receta/{0}'.format(id_receta))
form = ComentarioForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/receta/{0}'.format(id_receta))
else:
form = ComentarioForm(initial={'receta': id_receta})
cxt = {'receta':dato,'comentarios':comentarios,'form':form}
return render_to_response('menus/receta.html', cxt, context_instance=RequestContext(request))
receta.html
...
...
<form action="/receta/{{ receta.id_receta }}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Grabar">
<input type="button" value="Cancelar" onclick="window.location.href='/receta/{{ dato.id }}'"/>>
</form>
...
...
Of course, you should use get_absolute_url instead of hardcoding URLs.
Thanks for help me Cesar, your answer help me, but my error is in the variable in receta.html
is {{ receta.id }} and in the button is the same the correct is
<form action="/receta/{{ receta.id }}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Grabar"/>
<input type="button" value="Cancelar" onclick="window.location.href='/receta/{{ receta.id }}'"/>
</form>
Thanks for your help and a friend who found the error