{% if firstpass != secondpass %}
errors.append('Passwords are not the same')
I am trying to make a page where users can change their personal information. This one in particular pertains to checking whether the password textbox (firstpass) and password re-entering textbox (secondpass) contain the same password. For some reason, I am getting a compiler error on the line with the != sign. Can anyone suggest why? : (
If my taught is right you need to append this error message to errors list. Then you need to change it a bit.
First you need to create a form in template. I just create a dummy form for understand what happening.
<form action="/password-confirm/" method="post">{% csrf_token %}
<input type="text" name="firstpass">
<input type="text" name="secondpass">
<input type="submit" name="">
</form>
Second Create a view in views.py.
def password_confirm(request):
if request.method == "POST":
firstpass = request.POST["firstpass"]
secondpass = request.POST["secondpass"]
if firstpass == secondpass:
// Write code if passwords are same.
else:
errors.append("Passwords are not the same")
return render(request, 'password_confirm.html')
Third in urls.py.
url(r'^password-confirm/$', 'happytenants.views.password_confirm', name='about_us'),
And if you need to display error in template, you just pass the variable to template.
def password_confirm(request):
...
return render(request, 'password_confirm.html', {"errors": errors})
Related
I'm trying to submit two forms within one view. First, a user shares a URL through the first form. My program then renders some graphs and will ask the user at the end of the page to fill out a form and submit it. Here's how I'm trying to solve it:
views.py:
if request == "POST":
if 'first-input-name' in request.POST: # or in request.POST.get('name')
# do something
elseif 'second-input-name' in request.POST: # or in request.POST.get('name')
# do something else
template:
<input type="submit" name="first-input-name"/>
<input type="submit" name="second-input-name"/>
This is the approach I found in answers to similar questions. However, in my requests.POST I don't find the name of my input, and therefore I don't get the expected behavior.
Any ideas on how to solve this?
I recommend a better and less difficult approach, that is to create different action urls with related functions:
In template:
<form action="{% url 'view-1' %}">
<input type="submit" name="first-input-name"/>
# other...
</form>
<form action="{% url 'view-2' %}">
<input type="submit" name="second-input-name"/>
# other...
</form>
In urls:
path(first/, first_view, name="view-1"),
path(second/, second_view, name="view-2"),
In views:
def first_view(request):
if request.method == "POST":
#do something...
def second_view(request):
if request.method == "POST":
#do something...
You can just have one form with two fields to reduce code complexity. And do the below
def single_view(request):
if request.method == "POST":
# i also advice you use underscore(AKA snake_case) instead of hyphens
first_input_name = request.POST.get("first_input_name")
second_input_name = request.POST.get("second_input_name")
This also mean in your inputs you will have value="first_input_name" and value="second_input_name" in your inputs
i am trying to build a django search functionality for my app but the input form keeps returning a none
views.py
def search(request):
if request.method == 'POST':
query = request.POST.get('text')
houses = Product.objects.filter(name__contains='query')
context = {
'houses':houses,
}
return render (request, 'searchresult.html', context)
search.html
<form>
<input type='text' placeholder='search houses>
<button type='submit'>Search</button>
</form>
First off, your python indentation is invalid, and your HTML is also invalid on the input line. I will assume this is a typo in the question, but if not, you have issues there.
Your main problem is the filter for houses:
houses = Product.objects.filter(name__contains='query')
is looking for a name containing the string "query". You need the variable you've just defined.
houses = Product.objects.filter(name__contains=query)
You have an indentation issue in the code you have posted.
You need to add action and method in your Form.
<form action="/url_of_search/" method="post">
Missing quote in input line.
<input type='text' placeholder='search houses'>
You need to use query instead of 'query' in the filter.
Product.objects.filter(name__contains=query)
Things missing in html code:
form action attribute
form method attribute
input field name attribute
<!-- add form attributes method and action -->
<form method="POST" action="{% url '<url_name>' %}">
<!-- add input attribute name to identify the field and pass the value in request body -->
<input type='text' placeholder='search houses' name='search_text'>
<button type='submit'>Search</button>
</form>
update views for search
def search(request):
if request.method == 'POST':
# use input field name to get the search text
query = request.POST.get('search_text')
houses = Product.objects.filter(name__contains=query)
context = {
'houses':houses,
}
return render (request, 'searchresult.html', context)
I've created a form which by submit uploads an item to the database. The problem is that if I press f5 it'll submit the form again, because of the URL is now different.
I have these two url patterns
urlpatterns = [
url(r'(?i)^CMS/$', views.CMS, name='CMS'),
url(r'^createItem/$', views.createItem, name='createItem')
]
and my view looks like this
def CMS(request):
form = itemCreateForm()
context = {
'form' : form,
'message' : 'Content Manage Site'
}
return render(request, 'CMS.html', context)
def createItem(request):
f = itemCreateForm(request.POST)
if f.is_valid():
f.save()
pass
form = itemCreateForm()
context = {
'form' : form,
'message' : 'ItemCreated!'
}
return render(request, 'CMS.html', context)
the CMS.html
{% if message %}
{{ message }}
{% endif %}
<div class='newItemFields'>
<form action="{% url 'kar:createItem' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</div>
my form
class itemCreateForm(ModelForm):
class Meta:
model = item
fields = ['name', 'type', 'price']
I start at homepage/CMS/ and fill in the form and press submit, and view function createItem runs and creates and saves the object in the database. And sends the user to homepage/CMS/createItem. And now everytime the user press f5 the createItem function will run again and insert another object into the database with the same values as the previous one, even though the input fields are empty (can't wrap my head around that).
I also twice write form = itemCreateForm() which I believe is dubious?
What I'd like to do is after createItem is run, it should send the user back to homepage/CMS/ and not homepage/CMS/createItem. Would that be the proper way to do it? Or is there a smart way of doing this.
At the end of your createItem function, you are rendering HTML of the page rather than redirecting. Instead, you need to do
return HttpResponseRedirect(reverse('kar:index'))
You will need to import HttpResponseRedirect and reverse which is used to resolve the URL through its name.
Check this out: https://docs.djangoproject.com/en/1.10/topics/forms/#the-view
What I'd like to do is after createItem is run, it should send the
user back to homepage/CMS/ and not homepage/CMS/createItem. Would that
be the proper way to do it? Or is there a smart way of doing this.
That would indeed be the proper and smart way to do it. Have one view handle both GET and POST and then redirect after successful form submission. This ensures that the user can't resubmit the form merely by refreshing. And you address your concern about repeating your code.
urlpatterns = [
url(r'(?i)^$', views.index, name='index'),
url(r'^createItem/$', views.createItem, name='createItem')
]
Then combine your views
def createItem(request):
if request.method == 'POST':
f = itemCreateForm(request.POST)
if f.is_valid():
f.save()
return HttpResponseRedirect('/homepage/CMS/')
else :
form = itemCreateForm()
context = {
'form' : form,
'message' : 'Content Manage Site'
}
return render(request, 'CMS.html', context)
Note that the code is now shorter, it gives proper feedback to the user when the form is not valid. And you can't refresh to submit the for twice. We need a small change to the template
<div class='newItemFields'>
<form action=method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
</div>
The message display part isn't needed anymore
In Django1.6, is there a way to pass a dynamic parameter to my view or URL without parsing the URL?
Ideally I would want a urls.py that looks like:
url(r'^dash/$',
dash_view.account_modify,
{'account': **dynamic_account_identifier_here**}
name='dash_account_modiy')
And in views.py:
def account_modify(request, account,
template_name='profile.html,
change_form=AccountModifyForm):
...
:param account:
comes from model:
class Dash(models.Model):
name = models.Charfield()
account = models.IntegerField()
....
Basically, I would really like to avoid a urls.py with the account identifier as part of the string, like:
url(r'^dash/(?P<account>\w+)/$',
dash_view.account_modify,
name='dash_account_modiy')
Any suggestions on how I can pass these values from the a template to the processing view for use in the AccountModifyForm (which expects that 'account' parameter)?
url(r'^dash/$',
dash_view.account_modify,
{'account': **dynamic_account_identifier_here**}
name='dash_account_modify')
You can't dynamically evaluate anything there, because the dictionary is evaluated only once, when the URL conf is loaded.
If you want to pass information from one view to another your three options are:
in the URL, which you don't seem to want to do
as GET or POST data
store it in the session in one view and retrieve it from the session in the next
If anyone cares...figured it out...
In the template:
{% for dash in dashes %}
blah blah blah
<form action="..." method="POST">
<input type="hidden" name="id" value="{{ dash.account }}">
{{ form.as_ul }}
<input type="submit" value="Do stuff">
</form>
{% endfor %}
In the views:
if request.method == 'POST'
account = request.POST['id']
# be sure to include checks for the validity of the POST information
# e.g. confirm that the account does indeed belong to whats-his-face
form = AccountModifyForm(request.POST, account,
user=request.user)
....
I'm using the code found here (SO.com) to use the same template to both add and edit a record, but when I add a new record and click Submit, I get a 404 on the URL http://192.168.1.3:5678/app/student/edit/None/, and I'm not exactly sure why.
Here is the relevant portion of my urls.py:
url(r'^app/lesson/new/$', 'edit_lesson', {}, 'lesson_new'),
url(r'^app/lesson/edit/(?P<id>\d+)/$', 'edit_lesson', {}, 'lesson_edit'),
Here is the relevant portion of my views.py:
def edit_lesson(request, id=None, template_name='lesson_edit_template.html'):
if id:
t = "Edit"
lesson = get_object_or_404(Lesson, pk=id)
stu = get_object_or_404(Student, pk=sid)
if stu.teacher != request.user:
raise HttpResponseForbidden()
else:
t = "Add"
lesson = Lesson()
if request.POST:
form = LessonForm(request.POST, instance=lesson)
if form.is_valid():
form.save()
# If the save was successful, redirect to another page
return view_lessons(request)
else:
form = LessonForm(instance=lesson)
return render_to_response(template_name, {
'form': form,
't': t,
'lesson': lesson,
}, context_instance=RequestContext(request))
And finally, here is my template:
<h1>{{ t }} Lesson</h1>
<form action="/app/lesson/edit/{{ lesson.id }}/" method="post"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
I'm certain that I'm missing something really easy, but I can't seem to put my finger on it. I'm using Django 1.3.1 if that makes any difference.
Thanks,
MC
There's no need to specify any URL in the form's action attribute. Just do
<form action="" method="post">
and it will POST back to the URL that you originally used to access it, which is what you want.
In add case {{ lesson.id }} is None, because lesson is unsaved Lesson() instance, without pk, so your form is being fired to nonexistent URL.
I recommend separating create and edit views and processing them in different ways (or even inherit generic views - with new class-based generic views it's easy and pleasant).
Also, use {% url %} template tag everywhere instead of hard-coded urls.