Jump to page in Django - django

Alright, here is what I want to do:
A user sees a number of assignments in a table, with each assignment paginated using paginator. A user can input a number in a field and click "go", he is then taken to the page.
Here's my code so far:
View:
def home(request):
if request.user.is_authenticated():
assignments = show_assignments(request)
form=GoToForm(request.POST or None)
if request.POST and form.is_valid():
form = form.cleaned_data
assignment = form["assignment"]
page = form["page"]
return HttpResponseRedirect("/coding/assignment/%i/?page=%i") % (assignment, page)
return render(request, 'account.html', {'assignments':assignments, 'form':form})
Template:
{% for assignment in assignments %}
<tr>
<td><a href="{% url 'coding:assignment' assignment.id %}">
{{ assignment.country }}: {{ assignment.start_date }} to {{ assignment.end_date }}</a></td>
<td>{{ assignment.finished_articles }} of {{ assignment.article_num}} articles finished </td>
<td>Start where I left off</td>
<td>
<form id="form" action="" method="post" accept-charset="utf-8">
{% csrf_token %}
Jump to page {{ form.page }}
<input type="hidden" name="" value="{{ assignment.id }}" id="id_assignment">
<input type="submit" value="Go">
</form>
</td>
</tr>
{% endfor %}
This isn't working.
Is this because I need to use formsets (because I have multiple GoToForms on one page), or is the HttpResponseRedirect not working?

If the GoToForm form class looks simple (e.g. it only has page field), then there's no need to use this form class at all. Just add form fields manually in template and validate them inside post view if needed.
Formset for this case would be overkill, unless you have a lot of input fields to work with.
Also remember to change id="form" to make it unique for each form or use class="form" instead.

Related

How to save checkbox value in django?

I am using checkboxes in Html and everytime I refresh my page, the checkboxes are unchecked again. How do I prevent this from happening ? Do I have to use JS ?
I tought about booleans fields but I don't really know how to implement them ...
I looked at other threads and it talked about javascript, but I do not understand anything at all about it, nor how to implement it.
Here is my code :
views.py :
'
#login_required(login_url='/login')
def home(request):
check=False
MyToDo = Todo.objects.filter(user=request.user)
formtoDo = forms.TodoForm()
if request.method == 'POST' and 'todosub' in request.POST:
formtoDo = forms.TodoForm(request.POST)
if formtoDo.is_valid():
todoit = formtoDo.save(commit=False)
todoit.user = request.user
todoit.save()
return HttpResponseRedirect('/home?')
[...]
data ={'form': form, 'formtoDo': formtoDo, 'MyToDo': MyToDo, 'check':check}
return render(request, "capygenda/entries.html", data)
'
html :
<form method="POST", class="Entry">
{% csrf_token %}
<p>{{ formtoDo|crispy}} <button type="submit" name="todosub" >Add</button></p>
</form>
{% csrf_token %}
{% for toto in MyToDo %}
<form method="POST">
{% csrf_token %}
<ul class="list">
<li class="list-item">
<input type="checkbox" class="hidden-box" id="{{ toto.id }}" autocomplete="off"/>
<label for="{{ toto.id }}" class="check--label">
<span class="check--label-box"></span>
<span class="check--label-text">{{ toto }}</span>
</label>
<button class="button-24" role="button">Delete</button>
</ul>
</form>
Two steps:
In your views, if the form is submitted i.e., when request.method == 'POST' is True, pass another parameter {'checked: 'checked'}:
if request.method == 'POST' and 'todosub' in request.POST:
formtoDo = forms.TodoForm(request.POST)
if formtoDo.is_valid():
todoit = formtoDo.save(commit=False)
todoit.user = request.user
todoit.save()
return HttpResponseRedirect('/home?')
[...]
# ---- here look at the last item ----
data ={'form': form, 'formtoDo': formtoDo, 'MyToDo': MyToDo, 'check':check, 'checked':'checked'}
return render(request, "capygenda/entries.html", data
In your template, place that variable as an attribute in the input HTML element:
<input type="checkbox" class="hidden-box" id="{{ toto.id }}" autocomplete="off" {{ checked }}/>
This way, the checked attribute of the input will be dynamically placed. If it was passed via POST method, you have it. Otherwise, it's just empty.
add checked in the input field if you want it to keep it pre-checked or dependent on View values.
<input {% if checked %} checked{% endif %}"/>

Django - do not validate the second form

I have this code snippet in template.
<form method="POST" novalidate>
{% csrf_token %}
{{ form }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>
And in forms.py there are two forms (not ModelForm, but only Form).
form searches data in first db and form2 search data in second db and displays the results. The second form has only one field and I'd like to have something like this in
a view.
if request.method == "POST":
if form.is_valid():
# extract data from the first db
if form2.is_valid()
# extract a few more data from the second db
The field in the second form is not required for the user to fill in. If the user fills it in the user gets only more data displayed.
I solved it partially with the novalidate in HTML. But what I'd like to have is the validation of the first form and the second form with its one form field can be empty.
Is there some django feature to achieve this result?
something like this?
<form method="POST">
{% csrf_token %}
{{ form.novalidate }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>

Django template language syntax

I'm learning django and i'm blocked on a template syntax error.
I have this function in my views.py :
def AccountUpdateView(request):
template_name='portal/accountupdate.html'
context = {"forms":UserForm}
return render(request,template_name,context)
There is my template :
<form action="/account/update/" method="POST">
<ul>
{% csrf_token %}
{% for form in forms %}
<li>{{form.label}}
<input type="text" name="{{form.name}}" maxlength="32" required="" id="id_{{form.name}}" value="{{PLEASE HELP ME !!!}}">
</li>
{%endfor%}
</ul>
<input type="submit" value="Metre a jour" />
</form>
Well, i'm trying to get in the "value" of each form on my template by the current registered user known in django by the call {{user}}
And i would to auto place the values of each forms.
I think a solution is to use the form.name (for the example of the case 'username') and in the value call a thing like this :
user.form.username
It doesn't work and i know that i was dream to hope this exotic call don't work...
If any have a solution :)
Thank's you !
You shouldn't do this at all. Django will automatically output the whole field if you ask it.
For a start, use proper names for your objects. Secondly, if you want to prepopulate the form with data from the current user, then do so in the view. Note, you also need to deal with the posted data:
def AccountUpdateView(request):
template_name='portal/accountupdate.html'
if request.method == 'POST':
form = UserForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('/')
else:
form = UserForm(instance=request.user)
context = {"form":form}
return render(request,template_name,context)
Now, use the proper values and attributes in the template:
{% for field in form %}
<li>{{ field.label_tag }}
{{ field }}
{{ field.errors }}</li>
{% endfor %}

In django, how to use another model data from function based views

So I have a form that updates a key_instance object with a borrower. Currently my app needs the user to enter the name of the borrower, but I want it to display a dropdown list of data from another model the user model to select from, is there anyway to do this in a class based view? Here are my views.py and my template. What I was thinking is that I would like to use a get_list_or_404 on the user model and display it as a drop down list in the template and use that selection to populate the form field.
I manged to get the dropdown list to display in my template but I'm not sure as to how to save that value in my views.
Does anyone know if this is the right way or if this is doable? Thank you!!
views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(Users)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = UpdateKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = form.cleaned_data['borrower']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
form = UpdateKeyForm(initial={'borrower': 'N/A'})
return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst':key_inst})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
<table style="display: inline-flex">
{{ form}}
</table>
<select name = 'name'>
{% for name in names %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
Here is how I manged to do it, Not sure if this is the best 'pythonic' or best practice. Please let me know if it's not.
my views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(User)
# If this is a POST request then process the Form data
if request.method == 'POST':
name = request.POST['name']
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = name
key_inst.save()
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
pass
return render(request, 'catalog/keyinstance_request_update.html', {'keyinst':key_inst, 'names':names})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
</br>
<select name = 'name' required>
{% for key in names %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}

Form to display checkbox with title without the ability to edit title

I've been playing around with Django forms and it's a bit of a headache. I came to a point where I can display my form properly but I only want to edit part of it's data, not all of them.
Specifically: I have a Product model that has a title and a featured bool field. I want a form that displays all the products names with a tickbox next to it. The user is able to edit the featured property of each Product on the same form, but only that! My problem is that with the current setup, the displayed title is also an input field, not a simple text. If I change the template to display {{ productForm.title.value }} instead of {{ productForm.title }} it displays it as a text but the form failes the validation (It requires the title to have a value, since it cannot be null).
Model is plain simple, title and featured fields with CharField and BooleanField types. Validation branch is also not taken care of in the sample but "is_valid()" returns false.
views.py
def featured_product(request):
FeaturedProductFormSet = modelformset_factory(Product, fields=('title', 'featured'))
if request.method == "POST":
productForms = FeaturedProductFormSet(request.POST)
if productForms.is_valid():
productForms.save()
return redirect('/admin/')
else:
productForms = FeaturedProductFormSet()
return render_to_response(
'vetco_app/featured_products.html',
{
'productForms': productForms,
},
context_instance=RequestContext(request)
)
featured_products.html
<form action="" method="post">
<table>
<thead>
<th>
Termék neve
</th>
<th>
Kiemelt
</th>
</thead>
<tbody>
{% for productForm in productForms %}
{% if not forloop.last %}
<tr>
<td>
{{ productForm.id }}
{{ productForm.title }}
</td>
<td>
{{ productForm.featured }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<p>
{{ productForms.management_form }}
{% csrf_token %}
<button type="submit" name="action" value="Save">Save</button>
</p>
How to make it display only the text of the title without the need to validate it?
Simply provide context:
from django.template import RequestContext
context = RequestContext(request, {"your_model":your_model")
now in templates just write:
{{ your_model.some_attribute }}