Simple Form-Handling djangobook, version 2 - html

I am writing a simple search view. My views.py code is
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
else:
books = Book.objects.filter(title__icontains=q)
return render(request, 'search_results.html', {'books': books, 'query': q})
return render(request, 'search_form.html', {'error': error})
My search_results.html is
<p>You searched for: <strong>{{ query }}</strong></p>
{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No books matched your search criteria.</p>
{% endif %}
My search_form.html is
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action="" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
The problem is it is not switching on error = True condition. It is suppose to go to search_form.html in case of error and should reload the search form with error message in red. but it went to search_result.html in both cases.
Any help will be appreciated.

The django doc explains very well how to work with forms. I think you should read : https://docs.djangoproject.com/en/1.6/topics/forms/

Related

Formset not showing label in django

I am developing a domestic worker booking app in django
When I try to pass the formset, I am not geting the label of that field. I am only getting the field in html.
{% for formset in formsets %}
<form method="post">
{% for form in formset %}
{% for field in form %}
<div>
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
{% endfor %}
<input type="submit" value="Submit">
</form>
{% endfor %}
This the html code
def staffApply(request,pk):
if request.method == 'POST':
selected_domestic_works = request.POST.getlist('domestic_works')
formsets = []
if 'cook' in selected_domestic_works:
formsets.append(CookingForm(request.POST,prefix='cook'))
if 'driver' in selected_domestic_works:
formsets.append(DriverForm(request.POST,prefix='driver'))
print(formsets)
return render(request, 'staffApply2.html', {'formsets': formsets})
return render(request,'staffapply.html',{'uid':pk})
enter code here
This is my views.py
class CookingForm(ModelForm):
food_cooked=(('veg','veg'),
('non-veg','non-veg'),
('both','both')
)
class Meta:
model = Cook
fields = '__all__'
exclude=['user']
widgets={
'food_cooked':forms.widgets.RadioSelect(),
'type_of_cuisine':forms.widgets.CheckboxSelectMultiple()
}
This is my forms.py
I am getting the fields to type. But I am not getting hte label for those fields. Please help me fix this.
class Cook(models.Model):
food_cooked=(('veg','veg'),
('non-veg','non-veg'),
('both','both')
)
type_of_cuisine=(('NorthIndian','NorthIndian'),
('SouthIndian','SouthIndian'),
('Chettinadu','Chettinadu'),
('Chinese','Chinese'),
)
user=models.ForeignKey(User,on_delete=models.CASCADE)
food_cooked=models.CharField(choices=food_cooked,max_length=30)
type_of_cuisine=models.CharField(choices=type_of_cuisine,max_length=30)
experience=models.IntegerField()
wages_expected=models.IntegerField()
dishwashing_flag=models.BooleanField()
wages_for_dishwashing=models.IntegerField(null=True)
desc=models.TextField(max_length=200)
This is my models.py
You have one extra loop, with the wrong naming so you cannot access {{ field.label }} on your loops its like you are trying something like {{ form.field.attribute.label }}, the correct way would be the following:
{% for form in formsets %}
<form method="post">
{% for field in form %}
<div>
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
<input type="submit" value="Submit">
</form>
{% endfor %}
That being said, you can also use Django form rendering options, instead of doing it manually.
{% for form in formsets %}
<form method="post">
{{form.as_p}}
<input type="submit" value="Submit">
</form>
{% endfor %}

Django custom selection HTML page for django admin form

I have created a custom html template with basic checkboxes to select a value and return the value to the Django admin page.
I have done a 100 times before, but now the value of the selected superprofile does not get captured by the variable "selected_value" in the admin.py
The if statement "if request.method == 'POST':" is getting triggered but i keep getting the value of "selected_value" as none
Driving me crazy, I cannot find anything wrong in the code
The Html template
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}
{{ media }}
{% endblock %}
{% block content %}
<form class="change_superprofile_parent_form" method="POST" class="change_superprofile_parent_form">{% csrf_token %}
{% for superprofile in superprofiles %}
<input type="checkbox" name="superprofile_selected" {{ superprofile.checked }} value="{{ superprofile }}"> {{ superprofile }}<br>
{% endfor %}
<input type="submit" value="Submit">
</form>
{% endblock %}
Django admin.py
def change_superprofile_parent(self, request, queryset):
"""
Action to change the superprofile of the selected
"""
queryset = queryset.values_list("id", flat=True)
if request.method == 'POST':
selected_value = request.POST.getlist('superprofile_selected')
eligible_superprofiles = SuperProfile.objects.filter(status='Active')
return render(
request, 'admin/auth/user/change_superprofile_parent.html', context={
'superprofiles': eligible_superprofiles,
}
)

Django Form.Errors message is not showing and not printing in console

I am learning django forms right now. I can not see the output of the error in the website as a text message, it only shows as a pop-up message with the default error message even though I set my own error message. Also, my console is not printing anything after
if form.is_valid():
This is my views.py file:
def forms(request):
if request.method == 'POST':
form = Forms(request.POST)
if form.is_valid():
print("hello")
form.save()
print(form.cleaned_data)
return HttpResponseRedirect('/thank_you')
else:
form = Forms()
return render(request, "form/index.html", {
'form': form
})
def thank_you(request):
return render(request, 'form/thankyou.html')
And here's the html file
<html lang='en'>
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/thank-you" method="POST">
{% csrf_token %}
{{ form.name.label_tag}} <br>
{{form.name}} <br>
{{form.name.errors}}
<button type="submit">Send</button>
</form>
Try this in your template to show error message:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<strong>{{ error|escape }}</strong>
{% endfor %}
{% endfor %}
{% endif %}
And Here is solution for custom error message.

Validating for reCAPTCHA in flask

I'm making an error form on my website and it still works fine except for the captcha which is a bit silly. If I fill in all the fields on the text and do not just fill in the captcha, it will still be sent to me and without warning or anything, my validations that I set there will not respond, I need to help with it.
HTML Code:
<form action="{{ url_for('get_contact') }}" method=post>
<div>
<p>
{{ form.csrf_token }}
{{ form.name.label }} <br>
{{ form.name(placeholder='Jméno') }}
<ul>
{% for error in form.name.errors %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
<p>
{{ form.email.label }} <br>
{{ form.email(placeholder='Email') }}
<ul>
{% for error in form.email.error %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
</p>
<p>
{{ form.message.label }}<br>
{{ form.message(placeholder='Zpráva') }}
</p>
<p>
{{ form.recaptcha }}
{% for error in form.recaptcha.errors %}
<ul>
<li>{{ error }}</li>
{% endfor %}
</ul>
<input class="contact-submit" type="submit" value="Submit">
Flask Code:
#app.route('/contact', methods=["GET","POST"])
def get_contact():
form = ContactForm()
if request.method == 'POST':
name = request.form["name"]
email = request.form["email"]
message = request.form["message"]
res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
res.to_csv('./contactDatabase.csv', mode='a', header =False)
return redirect(url_for("rgb"))
else:
return render_template('contact.html', form=form)
Flask forms code:
class ContactForm(FlaskForm):
name = TextField("Jméno", [validators.DataRequired(), validators.Length(max=255)])
email = StringField("Email", [validators.DataRequired(), validators.Length(min=6, max=35)])
message = TextAreaField("Zpráva")
recaptcha = RecaptchaField()
You may have forgotten to use form.validate_on_submit()
#app.route('/contact', methods=["GET","POST"])
def get_contact():
form = ContactForm()
if request.method == 'POST' and form.validate_on_submit():
name = form.name
email = form.email
message = form.message
res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
res.to_csv('./contactDatabase.csv', mode='a', header =False)
return redirect(url_for("rgb"))
else:
return render_template('contact.html', form=form)
I didn't test the code above so I don't know if it's working.
Check if app.testing is True. 1
The flask-wtforms documentation states that:
For your convenience, when testing your application, if app.testing
is True, the recaptcha field will always be valid.
Also, don't forget you have to set the RECAPTCHA_PUBLIC_KEY and RECAPTCHA_PRIVATE_KEY configuration variables with the respective public and private keys received from your ReCaptcha registration.
1 It returns True if you set it to True directly or setting TESTING to True.

Action attribute in html form tag is not sending the data in django

I want to send song.id from each song in an album model but every time I send it, I get A KeyError
This is what I wrote in details.html
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form action="{% url 'music:favorite' album.id %}">
{% csrf_token %}
{% for song in album.song_set.all %}
<input type="radio" id="song{{ song.id }}" name="song" value="{{ song.id }}">
<label for="song{{ song.id }}">
{{ song.song_title }}
{% if song.is_favorite %}
<img src="https://png.pngtree.com/png-vector/20190726/ourmid/pngtree-cute-light-star-with-black-frame-png-image_1633374.jpg">
{% endif %}
</label>
<br>
{% endfor %}
<input type="submit" value="Favorite">
</form>
This is my views.py
def favorite(request, album_id):
album = get_object_or_404(Album, pk=album_id)
try:
selected_song = album.song_set.get(pk=request.POST['song'])
except (KeyError, Song.DoesNotExist):
return render(request, 'music/detail.html', {
'album':album,
'error_message':"You did not select a valid song",
})
else:
selected_song.is_favorite = True
selected_song.save()
return render(request, 'music/detail.html', {'album':album})
I am answering my own question. So in the form tag, I had to include the method attribute and set it to POST.
Change
<form action="{% url 'music:favorite' album.id %}">
To
<form action="{% url 'music:favorite' album.id %}" method="POST">