How to "remember" form selection value in Django?
{% load i18n %}
<form action="." method="GET" name="perpage" >
<select name="perpage">
{% for choice in choices %}
<option value="{{choice}}" {% if 'choice' == choice %} selected="selected" {% endif %}>
{% if choice == 0 %}{% trans "All" %}{% else %}{{choice}}{% endif %}</option>
{% endfor %}
</select>
<input type="submit" value="{% trans 'Select' %}" />
</form>
sorry about my words, but this seems a bad aproach. The django way to work with this is a simple form with a initial value for your selected choice. If you don't belive me, and you persist in this way, then change your template if as:
{% if choice == myInitChoice %}
Don't forget to send myInitChoice to context.
c = RequestContext(request, {
'myInitChoice': request.session.get( 'yourInitValue', None ),
})
return HttpResponse(t.render(c))
#register.inclusion_tag('pagination/perpageselect.html', takes_context='True')
def perpageselect (context, *args):
"""
Reads the arguments to the perpageselect tag and formats them correctly.
"""
try:
choices = [int(x) for x in args]
perpage = int(context['request'].perpage)
return {'choices': choices, 'perpage': perpage}
except(TypeError, ValueError):
raise template.TemplateSyntaxError(u'Got %s, but expected integer.' % args)
i just added takes_context='True' and take the value from context. The template i edited as
{% load i18n %}
<form action="." method="GET" name="perpage" >
<select name="perpage">
{% for choice in choices %}
<option value="{{choice}}" {% if perpage = choice %} selected="selected" {% endif%}>
{% if choice == 0 %}{% trans "All" %}{% else %}{{choice}}{% endif %}</option>
{% endfor %}
</select>
<input type="submit" value="{% trans 'Select' %}" />
</form>
Generally when you run into a common tasks, chances are there is an easy way to do it in django.
from django import forms
from django.shortcuts import render, redirect
FIELD_CHOICES=((5,"Five"),(10,"Ten"),(20,"20"))
class MyForm(froms.Form):
perpage = forms.ChoiceField(choices=FIELD_CHOICES)
def show_form(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
return redirect('/thank-you')
else:
return render(request,'form.html',{'form':form})
else:
form = MyForm()
return render(request,'form.html',{'form':form})
In your template:
{% if form.errors %}
{{ form.errors }}
{% endif %}
<form method="POST" action=".">
{% csrf_token %}
{{ form }}
<input type="submit" />
</form>
Related
hello thank you for your visiting
I'm a new learner of Django
I would like to know how to style form using django-bootstrap-v5
i try this and does not work
i have this form.py
pathesForm = inlineformset_factory(
Book,
quotation,
fields=('name','time',),
can_delete=False,extra=4,max_num=4,
widgets={'name': forms.TextInput(attrs={
'placeholder': 'name of book',
})
}
)
i use django-bootstrap-v5 and in file html
this form is not working with me
<form role="form" class="form-horizontal" method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="row">
<div class="col-md-6">
{% bootstrap_field form.name %}
</div>
<div class="col-md-6">
{% bootstrap_field form.time %}
</div>
</div>
{% if form.maybemissing %}
{% bootstrap_field form.maybemissing %}
{% endif %}
{% endfor %}
<button type="submit">Save</button>
</form>
but this is working with me (i can save the form)
{% bootstrap_formset_errors formset %}
<form role="form" class="form-horizontal" method="post">
{% csrf_token %}
{% bootstrap_formset formset %}
<button type="submit">Save</button>
</form>
this is my view.py
def hello(request,id):
book=Book.objects.get(id=id)
if request.method == 'POST':
form= pathesForm(request.POST,request.FILES,instance=book)
if form.is_valid():
form.save()
form = pathesForm(instance=book )
return render(request,'hello/pathesForm.html',{'formset':form})
i use print('hello) to try know where is the problem and the result seems like the form is not valid
how i can to customize the style of my form like the first one
in your views you forgot to pass then else statement so here it is
def hello(request,id):
book=Book.objects.get(id=id)
if request.method == 'POST':
form= pathesForm(request.POST,request.FILES,instance=book)
if form.is_valid():
form.save()
else:
form = pathesForm(instance=book)
return render(request,'hello/pathesForm.html',{'formset':form})
and in your html while requsting the file field
you have to give form a encryptio type here it is
<form role="form" class="form-horizontal" method="POST" enctype="multipart/form-data">
this has to solve your problem and tell me if you still getting any error have a good day
allways if you have a problem with from use print(form.errors) before the form is valid and after it
i got my problem and i got this error [{'id': ['This field is required.']}
soulition:
<form role="form" method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="row">
<div class="col-md-6">
{% bootstrap_field form.name %}
</div>
</div>
{% if form.maybemissing %}
{% bootstrap_field form.maybemissing %}
{% endif %}
{% endfor %}
i think it success using formset only because of ( id add automatically )
and if you want to forloop you should be add it manually
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
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)
Below is the view
def TestPageView(request):
if request.method == 'POST':
contactform = ContactForm(request.POST,prefix="contact")
subscriptionform = SubscriptionForm(request.POST,prefix="subscription")
suggestionform = SuggestionForm(request.POST,prefix="suggestion")
globalmessageform = GlobalMessageForm(request.POST,prefix="globalmessage")
if contactform.is_valid() and subscriptionform.is_valid() and suggestionform.is_valid() and globalmessageform.is_valid():
contact = contactform.save()
subscription = subscriptionform.save()
suggestion = suggestionform.save()
globalmessage = globalmessageform.save()
else:
print(form.errors)
else:
contactform = ContactForm(prefix="contact")
subscriptionform = SubscriptionForm(prefix="subscription")
suggestionform = SuggestionForm(prefix="suggestion")
globalmessageform = GlobalMessageForm(prefix="globalmessage")
return render(request,'dashboard/test_page.html',{'contactform':contactform,'subscriptionform':subscriptionform,'suggestionform':suggestionform,'globalmessageform':globalmessageform})
How to write html code to show and save these forms on test_page.html.I know how to show one form but there are 4 forms in this case.
I have coded like this but i cannot see any output on test_page.html. Page is completely blank.
{% extends "base.html" %}
{% block content %}
{% load static %}
<div>
<div>
<form method="post" >
{% csrf_token %}
{{ contactform.as_p }}
</form>
</div>
<div>
<form method="post" >
{% csrf_token %}
{{ subscriptionform.as_p }}
</form>
</div>
<div>
<form method="post" >
{% csrf_token %}
{{ suggestionform.as_p }}
</form>
</div>
<div>
<form method="post" >
{% csrf_token %}
{{ globalmessageform.as_p }}
</form>
</div>
<input type="submit" name="Save">
</div>
{% endblock %}
I am trying to display a message on a template that varies based on the boolean field in my model.
For my model I have:
Class Example(models.Model):
completed = models.BooleanField(default=False)
Views.py
def home(request):
example = Example.objects
return render(request, 'home.html', {'example': example})
home.html
{% for x in example.all %}
{% if x.completed %}
<p>Congratulations!</p>
{% else %}
<p>Try again!</p>
{% endif %}
{% endfor %}
The template always displays "Try again!" even though through the Admin I have ensured that some are True and some are False.
Your views.py should be like this
def home(request):
example = Example.objects.all()
return render(request, 'home.html', {'example': example})
and html should be
{% for x in example %}
{% if x is True %}
<p>Congratulations!</p>
{% else %}
<p>Try again!</p>
{% endif %}
{% endfor %}
The is a simple way I thought of handling boolean related option field in a form
Model.py:
class example(models.Model):
is_online = models.BooleanField(default=False)
Example.html:
<div class="form-row">
<div class="col-md-4 mb-3">
<label class="sr-only">Class Type</label>
<select name="types" class="form-control">
<option selected="true" disabled="disabled">Type (All)</option>
<option value="True"
{% if 'True' == values.types %}
selected
{% endif %}
>Online</option>
<option value="False"
{% if 'False' == values.types %}
selected
{% endif %}
>Classroom</option>
</select>
</div>
</div>
View.py
# Types
if 'types' in request.GET:
types = request.GET['types']
if types == 'True':
queryset_list = queryset_list.filter(is_online=True)
elif types == 'False':
queryset_list = queryset_list.filter(is_online=False)