process 2 forms from 2 html files in Django - python

Sorry for my bad english
I've got "topics.html" file, that extends "base.html".
In "base" I've got search form. In "topics" I've got any checkboxes. How can I connect 2 forms in 1 request?
Base:
<form id="form_1" action="{% url 'topics' %}"><input type="search" id="search" name="search" placeholder="Search"></form>
Topics:
<form id="form_1" action="{% url 'topics' %}">
<div class="typess">
<h1 class="vk">Categories:</h1>
{% for typee, name in types.items %}
<label>
<input type="checkbox" style="display:none" value="{{ typee }}" name="category" {% if typee in categories %} checked {% endif %}>
<span class="typee" title="{{ name }}"><i class="{{ typee }}"></i>{{ name }}</span>
</label>
{% endfor %}
</div>
</form>
It should connect in "topics" function:
def topics(request):
info = []
categoriess = request.GET.getlist('category')
typess = request.GET.getlist('type')
search = request.GET.get('search')
if categoriess:
...
But when I run code, it's not see the checkboxes

Related

Django - Updating value only for the last item of list

This is how my ToDoapp looks like
The date change works only for the last item in the list but for other items it throws the error:
ValidationError at /
['“” value has an invalid date format. It must be in YYYY-MM-DD format.']
I see that irrespective of "Update" button I press, it passes only the last item's id and date.
Find my code below:
Index.html
{% extends 'base.html' %}
{% block content %}
<h3 style = "margin-bottom: 20px"><strong>To Do List App</strong></h3>
<form method="POST">
{%csrf_token%}
<ul class="list-group">
{% for task in tasklist %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<input type='hidden' name = 'task_id' value='{{task.id}}'>{{task.tasks}}
<span class="badge bg-primary rounded-pill">{{task.duedate}}
<input type="date" name="datepick" />
<input type='submit' value ='Update'>
</span>
</li>
{% endfor %}
</form>
Views.py
def index(request):
if request.method == "POST":
task_id = request.POST.get('task_id')
task=Task.objects.get(id=task_id)
datepick = request.POST.get('datepick')
task.duedate = datepick
task.save()
tasklist = Task.objects.all()
return render(request, 'index.html', {'tasklist':tasklist})
Models.py
class Task(models.Model):
tasks = models.CharField(max_length=200)
duedate = models.DateField(blank=True)
I feel that mistake is in the HTML file and I'm not familiar with HTML.
Each task on the list should have its own form.
{% extends 'base.html' %}
{% block content %}
<h3 style = "margin-bottom: 20px"><strong>To Do List App</strong></h3>
<ul class="list-group">
{% for task in tasklist %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<form method="POST">
{%csrf_token%}
<input type='hidden' name = 'task_id' value='{{task.id}}'>{{task.tasks}}
<span class="badge bg-primary rounded-pill">{{task.duedate}}
<input type="date" name="datepick" />
<input type='submit' value ='Update'>
</span>
</form>
</li>
{% endfor %}
</ul>
Each row shall be in an independent form as currently the form has 3 elements with the same name
You should provide a unique name for each element in a form. As it is inside an iterator you can use {{ forloop.counter }} as name.
The link below would be helpful:
Django - iterate number in for loop of a template

Search bar no content is returned

Hey i am new to Django and I am trying to make a search bar to my first site.
My problem here is when I search for any value that I/user entered and on the site, the site only refreshes and doesn't give me anything back but the empty option that i gave the site to display when there is no content to match the search.
(That's not all of the Topic model)
model.py
class Topic(models.Model):
content = models.CharField(max_length=200)
views.py
def search(request):
query = request.GET.get('q')
if query:
result = Topic.objects.filter(content__icontains=query)
context = { 'query': query, 'result': result}
return render(request, 'learning_logs/topics.html', context)
(that's all of the topics.html i am sorry of how it turned this not what it really looks like on the original topics.html but that's the full topics.html )
topics.html
% extends "leaning_logs\base.html" %}
{% block page_header %}
<h1>Topics </h1>
<br>Add a new topic</br>
{% endblock page_header %}
{% block content %}
<form method="GET" action="{% url 'learning_logs:search' %}">
{% csrf_token %}
<input name="q" value="{{ request.GET.q }}" placeholder="search..">
<button class="btn btn-success" type="submit">
Search</button>
</form>
{% for topic in topics %}
<div class="card-mb3">
<div class="card-header" style="background-color:lightgrey">
<table class="table">
<tr>
<th>Image</th>
<th>Title of the topic</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<div class="card-body" style="background- color:white">
<tr>
<td>
{% if topic.image %}
<image src="{{topic.image.url}}" style="width:200px">
{% else %}
<span class="text-muted">No Image have been added</span>
{% endif %}
<td><h3>
{{topic}}
</td></h3>
<td><small><a href="{% url 'learning_logs:edit_topic' topic.id %}">
<button method="submit" class="btn btn-primary">
Edit topic</button></a></small></td>
<td><small><form method="post" action="{% url 'learning_logs:delete_topic' topic.id %}">
<button type="submit" class="btn btn-danger btn-primary" >
Delete topic</button></form></small></td>
</tr>
</div>
</div>
</div>
{% empty %}
<h3><li>No topics have been added yet.</li></h3>
{% endfor %}
{% endblock content %}
This:
{% for topic in topics %}
should be that:
{% for topic in result %}

Request in Flask from a Form in HTML is returning None Value, What should I Do?

I am getting no value on request in flask. It is returning None value.
I have tried changing the method but no use.
The flask code:
#app.route("/login/user/book")
def searchbook():
bookname=request.form.get("search")
return render_template("message.html",heading=bookname ,message=" ")
The webpage:
{% extends "layout.html" %}
{% block heading %}Welcome to BookSarkar{% endblock %}
{% block body %}
<p>Welcome {{ name }}</p>
<form action="{{ url_for('searchbook') }}" method="get" class="form-group">
<div class="form-group">
<input type="text" name="search" class="form-control col-md-6 mt-5 mx-auto" placeholder="Search books">
<p style="text-align:center;">
<button type ="submit" class="btn btn-primary mt-2 mx-auto">Search</button>
</p>
</div>
</form>
<div class="fixed-top m-2">
<a class="btn btn-outline-primary" href="{{ url_for('logout') }}" role="button" style="float:right;">Log out</a>
</div>
{% endblock %}
The message webpage:
{% extends "layout.html" %}
{% block heading %}{{ heading }}{% endblock %}
{% block body %}
{{ message }}
<a class="btn btn-primary" href="{{ url_for('index') }}" role="button">Return to Home Page</a>
{% endblock %}
The layout page has no bugs as all other pages are working fine. I expected the webpage to show the given input but it is showing None
request.form contains values submitted via post or put, while your form uses get. Try using request.args.get("search") instead of request.form.get("search")

error is not displayed in the template

I have used django allauth for user registration and login. I have used the {{ form.has_errors }} in template to show an error but the error is not displayed in the template. What might be the reason for not showing an error in the template?
The code from allauth login.html(account/login.html)
{% block content %}
<div class="login-box">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-6 col-md-offset-3 login-area">
<span class="error">
{% if form.has_errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
</span>
<div class="panel panel-default">
<div class="panel-heading login-header">{% trans "Sign In" %}</div>
<div class="panel-body">
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
<div class="form-group form-group-lg">
<label for="emailAddress">Email address</label>
<input type="email" class="form-control" id="emailAddress id_login" name="login" placeholder="Email">
</div>
<div class="form-group form-group-lg">
<label for="password">Password</label>
<input type="password" class="form-control" id="password id_password" name="password" placeholder="Password">
</div>
<div class="form-group">
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
</div>
<button class="btn-block signin-btn btn-sm btn-primary pull-right m-t-n-xs" type="submit">{% trans "Sign In" %}</button>
</form>
</div>
<div class="panel-footer">
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Try this one. Errors raised by the form which is not attached to field are stored in non_field_errors
{% if form.non_field_errors %}
<ul class='form-errors'>
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
or if you want to display in your way try this one
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
Seems to be a misunderstanding of has_error
his method returns a boolean designating whether a field has an error
with a specific error code. If code is None, it will return True if
the field contains any errors at all.
Coupled with the fact that you are rendering the form manually. Generally there are two types of form errors, non field errors and errors associated with each field (when their validation fails). The above method accepts a field name as a parameter and returns true if the field has failed validation.
You have several options, including continuing with your current approach but checking for form.errors instead of form.has_error or displaying the error with each field separately.

Getting from POST in included .html page in Django

I am trying to get the POST values of an .html page that has included pages via {% include %} in Django. However, it returns only the POST from the initial html page.
My inner html that is included has the snippet of code:
div id="edit_parameters">Edit Parameters</div>
<div data-id="{{job.slug}}" id="{{job.slug}}" class="collapse">
<form class = "form-inline" method="post">
{% csrf_token %}
{% for parameter in job.get_object.parameters %}
<p>
<input type="text" class="input-small" name="{{parameter}}" value="" id ="{{parameter}}-input" placeholder="{{parameter}}">
</p>
{% endfor %}
<button type="submit" class="btn btn-primary run-job">Submit</button>
</form>
</div>
{% else %}
<div>
No editable parameters for this job.
</div>
{% endif %}
And my outer HTML file has a snippet:
<ul id="available-jobs">
{% if jobs_same_io_type and jobs_diff_io_type %}<h3> Current Step </h3>
{% elif jobs_same_io_type %} <h3> Next Step </h3> {% endif %}
{% for job in jobs_same_io_type %}
{% include "includes/job_li.html" with add=1 %}
{% endfor %}
{% if jobs_diff_io_type %} <h3> Next Step </h3> {% endif %}
{% for job in jobs_diff_io_type %}
{% include "includes/job_li.html" with add=1 %}
{% endfor %}
{% if not jobs_same_io_type and not jobs_diff_io_type %}
<li class="full-height">There are no more available jobs.</li>
{% endif %}
</ul>
<fieldset class="submit">
{% csrf_token %}
<input type="hidden" name="job_to_run" value="" id="job-to-run" />
<input type="hidden" name="workflow_jobs" value="" id="ordered-jobs" />
<input type="hidden" name="job_to_edit" value="" id="job-to-edit" />
<input type="hidden" name="job_to_add" value="" id="job-to-add" />
<input type="hidden" name="job_to_remove" value="" id="job-to-remove" />
<input type="submit" name="done" value="I'm done, start the jobs" id="jobs-ready" />
</fieldset>
The everything that shows in post is in the inputs of the second snippet. But the parameters I want for the first snippet are not included when I use request.POST for all of the POST values.
Any help would be greatly appreciated in explaining why I am not getting the values from the included page and finding a possible solution. Thanks!
In HTML, only the fields in the form element that contain the submit button are included in the POST. the fields in your second file don't seem to be in any form at all, so they will never be posted.

Categories