django form view show error or not - python

I'm making a little personal project using Django framework and I get one question while making login view with django form.
I was struggled to show form error messages in my template, and I found a cause in my view.
This is view that showing error message
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
else:
form = LoginForm()
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)
another view that dosen't showing error message
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
form = LoginForm()
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)
and this is my template
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
{{ form.username}}
{{ form.password }}
{{ form.non_field_errors }}
<button id="login-btn" class="btn btn-default" type="submit">login</button>
The difference is just using elsephrase or not in view.
I think whether using elsephrase or not, there two views have logically same result... I don't understand difference of those two views.
Is there any clue to understand the differece of those two views?..
Thanks

You're overwriting the POST form by defining the form at the end. Load the blank form first
def login_view(request):
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
form.login(request)
return redirect('/')
context = {
'form': form,
}
return render(request, 'member/login.html', context=context)

Related

Django Form Not Saving the Data

I've imported this from django.contrib.auth.forms import UserCreationForm
used csrf_token in the form but still when I hit submit the page reloads but doesn't save the data to database.
def signup(req):
if req.method == 'POST':
form = UserCreationForm(req.POST)
if form.is_valid():
form.save()
form = UserCreationForm()
reg_con={
'regform': form
}
return render(req, 'signup.html', reg_con)
form
<form action="." method="POST">
{% csrf_token %}
{{ regform.as_ul }}
<input type="submit" value="Sign Up">
</form>
This is normally because something is wrong with your form the problem is however that you each time construct a new form, and you thus can not see what went wrong. You should only create a new form in case it is a GET request, so:
def signup(req):
if req.method == 'POST':
form = UserCreationForm(req.POST)
if form.is_valid():
form.save()
else:
form = UserCreationForm()
reg_con={
'regform': form
}
return render(req, 'signup.html', reg_con)
Try removing the action attribute from your form tag. Also don't forget to redirect after calling form.save()

Django register form POST data not validated by view in production?

For some reason the POST data from my Django app's user sign up form doesn't get validated by the signup view. It works perfectly in development on my local machine, but not in production. I have also inspected the web content and the POST data gets created but the page just reloads an empty form. What could cause this?
signup.html
<form method="POST" autocomplete="off" novalidate>
{% csrf_token %}
{% cache 86400 signup %}
...
<button type="submit">Sign up</button>
{% endcache %}
</form>
views.py
def signup_view(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
return redirect('home')
else:
form = UserRegisterForm()
context = {
'title': 'Sign up',
'form': form,
}
return render(request, 'users/signup.html', context)
Found it! The template caching was causing the form to render without the POST content, making it seem as if no validation is happening.

How to edit an object using model form in django?

This may possibly be a duplicate of this answer. Currently, i'm working on updating an object using the same model form that is used to create the object.
my views.py looks like: (as from the answer):
def newpost(request):
form = PostForm(request.POST)
if request.method == "POST":
if form.is_valid():
obj = form.save(commit=False)
obj.save()
return redirect('newpost')
return render(request, 'console/newpost.html', {'form':form})
def editpost(request, pk):
obj = Post.objects.get(id=pk)
form = PostForm(instance=obj)
if request.method == "POST":
if form.is_valid():
obj = form.save(commit=False)
obj.save()
return redirect('editpost')
return render(request, 'console/editpost.html', {'form':form})
And my html form in editpost looks like:
<form method="POST" action="{% url 'newpost' %}">
{% csrf_token %}
{{form.as_p}}
<button type="submit"> Submit</button>
</form>
and my urls.py looks like:
path('console/post/', c_views.newpost, name='newpost'),
path('console/post/<int:pk>/', c_views.editpost, name='editpost'),
And the above codes works perfectly fine, but creates a new instance, with the data of the object taken from pk.
I added a obj.delete() code like this:
def editpost(request, pk):
obj = Post.objects.get(id=pk)
form = PostForm(instance=obj)
obj.delete()
if request.method == "POST":
if form.is_valid():
obj = form.save(commit=False)
obj.save()
return redirect('editpost')
return render(request, 'console/editpost.html', {'form':form})
This code gives me the exact thing i wanted, but i know it's not a good practice. My question here is, is this a correct way or am i lagging somewhere.
I know the action in my editpost html should not be {% url 'newpost' %}, but if i use {% url 'editpost' %} i don't know how to pass the pk value inside the url tag. Can anyone suggest me the correct way?
Each of your views should accept GET and POST methods, when the method is GET the form is instantiated with no request.POST data passed to it and the form is just rendered.
def newpost(request):
if request.method == 'GET':
form = PostForm()
else: # POST
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('newpost')
return render(request, 'console/newpost.html', {'form':form})
def editpost(request, pk):
obj = Post.objects.get(id=pk)
if request.method == 'GET':
form = PostForm(instance=obj)
else: # POST
form = PostForm(request.POST, instance=obj)
if form.is_valid():
form.save()
return redirect('editpost')
return render(request, 'console/editpost.html', {'form':form})
<form method="POST">
If you do not set the "action" attribute on a form it will submit the data to the same URL that the browser is currently on. This way you can use the same template for both views

CSRF verification failed. Request aborted. Django 2.0

def order_view(request):
if request.method == 'POST':
form = OrderForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('Order Submitted')
else:
form = OrderForm()
return render_to_response('home/order.html', {'form': form})
order_view function in views.py
<form class="form form-table" method="post">
{% csrf_token %}
{{ form|crispy }}
<input class="btn br-green" type="submit" value="Submit"/>
</form>
There is still a CSRF error in it. Have tried most of the solution but they are not working.Have tried adding RequestContext(request) as well.
HttpResponseRedirect takes a url. I don't think 'Order Submitted' is.
Try
def order_view(request):
if request.method == 'POST':
form = OrderForm(request.POST)
if form.is_valid():
form.save()
else:
form = OrderForm()
return render_to_response('home/order.html', {'form': form})
If this works then you're sorted and use django.messages to provide the message to your user.

Django Form Fields won't show in my template

The form field won't show up in the browser. There is only the submit button showing up.
views.py code:
def vote(request, pk):
# check if request is post
if request.method == 'POST':
# create a form and populate it with data from request
form = forms.Vote(request.POST)
if form.is_valid():
fact = Fact.objects.get(pk=pk)
fact.votes += int(form.cleaned_data['vote'])
fact.save()
return HttpResponseRedirect(reverse(
'facts:detail',
args=(pk,)
))
else:
form = forms.Vote()
return render(request, 'facts/fact_detail.html', {'form': form})
template(fact_detail.html) code:
<form method='POST'>
{% csrf_token %}
{{ form }}
<input type="submit" value="vote" />
</form>
Form class(forms.py) code:
VOTE_CHOICES = [
(1, 'upvote'),
(0, 'downvote')
]
class Vote(forms.Form):
vote = forms.ChoiceField(choices=VOTE_CHOICES, widget=forms.RadioSelect())
In views.py for the vote method initialize the form variable locally, before passing it as a parameter.
def vote(request, pk):
form=""
//rest of the code//
return render(request, 'facts/fact_detail.html', {'form': form})
I recommend check generic editing views from django documentation I think it has the solution
[ https://docs.djangoproject.com/en/1.11/ref/class-based-views/generic-editing/#createview][1]

Categories