Trying my first app in Django, and have some problem on form validation (following documentation)
This is part of file upload code. The form creates fine. But, the validation fails.
Even though, I provide Title, it gives This field is required.
views.py
def upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
#TODO handle(request.FILES['file'])
return HttpResponseRedirect('/')
else:
form = UploadFileForm()
return render_to_response('setup.html', {'form': form},context_instance=RequestContext(request))
forms.py
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField()
file = forms.FileField()
setup.html
<form action="/setup/" method="post">{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
Add required paremeter to your form field. If you don't provide it Django will assume it is required.
title = forms.CharField(required=False)
Related
I extend the django User model with a profile model. I want add update user's profile function. Because I make the num field a unique field, in my update view function, the update form's is_valid was always False. I also cannot update the photo png? Here is my code;
Models:
class Profile(models.model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
num =models.CharField('identity',max_length=254,unique=True)
photo = models.ImageField('image',upload_to = 'images/licences')
forms:
class ProfileForm(forms.ModelForm):
class Meta:
model= Profile
fields = ['num','photo']
views:
def modify_view(request):
user = request.user
if request.method=="POST":
form = ProfileForm(request.POST,request.FILES)
if form.is_valid()
user_profile = Profile.objects.get(user=user)
user_profile.image = form.clean_data['image']
user_profile.save()
else:
form = ProfileForm()
return render(request,"profile.html",{form:form})
template
{% extends 'account/home/index.html' %}
{% block content %}
<div class="row">
<div class="col-md-8 col-sm-8 col-8">
<form class="signup needs-validation" id="signup_form" method="post" enctype="multipart/form-data" >
{% csrf_token %}
{{form.as_p}}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<div class="form-group">
<button type="submit" class="col-sm-8 offset-sm-4 btn btn-success btn-block">update</button>
</div>
</form>
</div>
</div>
{% endblock %}
Since num field is unique and will not be generated again on updating the profile image, you can ignore request.POST and pass the instance argument to the ProfileForm class.
Example:
def modify_view(request):
user = request.user
if request.method=="POST":
user_profile = Profile.objects.get(user=user)
form = ProfileForm(files=request.FILES, instance=user_profile)
if form.is_valid():
user_profile.image = form.clean_data['image']
user_profile.save()
else:
form = ProfileForm()
return render(request,"profile.html",{form:form}
I found out error message doesn't show up for some forms so I tried to do like this.
def add_entry(request):
if request.method != 'POST':
form = EntryForm(user=request.user)
else:
form = EntryForm(request.POST, user=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse_lazy('blog:list_entry'))
else:
print("error happened.")
context = {
'form': form,
}
return render(request, 'blog/add_entry.html', context)
and even when I tried to submit invalid data, it didn't output anything.
html
<form method="POST">
{% csrf_token %}
<div class="form-group">
{{ form.description.errors }}
<label>{{ form.description.label }}</label>
{{ form.description|add_class:'form-control' }}
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
models.py
class Entry(models.Model):
description = models.TextField(max_length=512)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
forms.py
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['description']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super().__init__(*args, **kwargs)
def save(self):
entry = super().save(commit=False)
entry.user = self.user
entry.save()
return entry
When I submit valid data, the form does work. What am I wrong with this?
It sounds like your browser validation is preventing the form from being submitted when the description field is empty.
You can work around this by adding novalidate to the form. The browser will then allow you to submit a request with description="", and you should see the error from Django in the response.
<form method="POST" novalidate>
{% csrf_token %}
<div class="form-group">
{{ form.description.errors }}
<label>{{ form.description.label }}</label>
{{ form.description|add_class:'form-control' }}
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
Im new with Django and Im trying to include my own form
My forms.py
class MyOwnForm(forms.ModelForm):
class Meta:
model = Album
fields = ['username']
My views.py
def testing_Form(request):
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
username = form.cleaned_data['username']
return render(request, 'form.html', {'form': form})
my form.html
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
and the last one form_template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2" >{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
When I open the Form Webpage, I get a empty entry field and the submit button. But when I click this button. The page is reloading and nothing more.
what do i have to do that i can work with the entered data?
But when I click this button. The page is reloading and nothing more.
Because of this, I'm assuming that you intend to show some information after the form is submitted. Here's a simple example that just displays an acknowledgement after the form is submitted.
{% if submitted %}
<div class="jumbotron contactainer">
<h1 class="display-4">Submitted</h1>
<hr class="my-4">
<p class="lead">{{ username }}'s album has been submitted</p>
</div>
{% else %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
{% endif %}
views.py
def testing_Form(request):
submit = False
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.username = request.user
album.save()
submit = True
username = form.cleaned_data['username']
return render(request, 'form.html', {'username':username, 'submitted':submit})
else:
return render(request, 'form.html', {'form': form, 'submitted':submit})
You can do anything you wish with the username variable or add new variables, just remember to add them to the context dictionary if you wish to display them. The submit variable I've added is used in the template to determine what to show. Hope this helps :)
Not quite sure what you are exactly trying to achieve. However if you want to show the value of your previous submit on your screen for example as: Previous submitted username: <input username>, you can use the defined form in your template, including the values if there was a submit before.
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
You can always add extra context to your template by assigning it to the context dictionary in the similar way you did with the {'form': form} as {'form': form, 'hello': "My hello string"} in your view.
In your template you could now use {{ hello }} as an variable.
Note that you are also using commit=False in your form to add more request data to the model after (user). Currently you left it in the unsaved state. To save the new form entry, you need to call album.save() after the modifications.
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.save() # now commit
The username = form.cleaned_data['username'] has been defined, but never been used. Which with the example above is no longer required.
You can fetch the album objects when the user is authenticated and pass them to the template to work with as context like:
(bad practice style, but just to give you an idea within the scope of your code)
if request.user.is_authenticated:
return render(request, 'login.html')
else:
form = AlbumForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
albums = Album.objects.all()
return render(request, 'formhandle/form.html', {'form': form, 'albums': albums})
Which you could show in your form template as:
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
<ul>
{% for album in albums %}
<li>{{ album.user.username }}</li>
{% endfor %}
</ul>
trying to create a registration form, and I am facing an issue. so, below are my python pages:
form.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(ModelForm):
class Meta:
model = User
fields = ('username','password','email')
models.py
from django.db import models
#from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Registration(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
urls.py
urlpatterns = [
url(r'^register/$', views.SignUpFormView, name= 'register'),
]
test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form }}
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit" />
</form>
{% endblock %}
{% endblock %}
views.py
def SignUpFormView(request):
template_name = 'test.html'
try:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
return render(request, template_name, {'form':form})
except ValueError:
print("Oops! That was not a valid entry, try again...")
else:
SignUpForm()
return render(request, 'user_info/about.html')
The issue is, my "SignUpFormView" function in views.py is not entering the "if" statement, its directly going to "else". I seem to be lost here.
I have 'about.html'. I do not see any error as well. Which I find very weird. Please help.
Note: I am using Django's default in-built "User" model, and I do not wish to create any custom model.
Modified views.py
def SignUpFormView(request):
user_form = 'SignUpForm'
template_name = 'test.html'
if request.method == 'POST':
form = user_form(request.POST)
if form.is_valid():
form.save()
#username = form.cleaned_data.get('username')
#password = form.cleaned_data.get('password')
#email = form.cleaned_data.get('email')
#user.save()
return render(request, template_name, {'form':form})
else:
SignUpForm()
return render(request, 'user_info/about.html')
Modified forms.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(forms.ModelForm):
#password = forms.Charfield(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','password','email')
modified test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
{% for error in form.errors %}
{{ form.errors | default_errors }}
{% endfor %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% for field in form %}
<p>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" value="Submit">sign up </button>
</form>
{% endblock %}
{% endblock %}
I am new to Django and looking to build a quick form with a response.
I am trying to build a form which would ask the user to input his name when the user clicks submit the page should reload and just say "Hello .
urls.py
class Question1Form(forms.Form):
n = forms.CharField(max_length=100,
widget=forms.TextInput(
attrs={'placeholder': 'Number', 'class': 'form-control'}))
views.py
def home(request):
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = [Question1Form.ans()]
return HttpResponse(Question1Form.n)
else:
form = Question1Form()
return render(request, 'index.html', {'form': form})
index.html
<form action="" method="post" class="form">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form-row form">
<div class="col-sm-4">
{{ form.n.errors }}
{{ form.n }}
</div>
<input class="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
So how the code s
You should call instance field, not class field and get value from validated(cleaned) data (see documentation):
return HttpResponse(form.cleaned_data['n'])
If you want to reload the same template with n value:
return render(request, 'index.html', {'form': form, 'n': form.cleaned_data['n']})
and at the template add:
{% if form.is_valid %}
<p> Hello {{ n }} </p>
{% endif %}
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = form.save()
return render(request, 'index.html', {'created': True})
Then in your HTML you can say
{% if created %}
<p> Hello </p>
{% endif %}
edit I see now you have no action in your form.
So you need to point to that view in your URLS.py.
for example.
from myapp import views as app_views
from django.conf.urls import url
urlpatterns =[
url(r'^my_form/$', app_views.home, name='save_form'),
]
And then add the action to your form.
<form action="{% url 'save_form' %}" method="post" class="form">