How to display custom errors in the template - python

I have function with custom errors, how to display these errors in the template
def auth_join(request, room, slug):
if request.method == 'POST':
user = request.user.username
form_auth = AuthRoomForm(request.POST)
if form_auth.is_valid():
room_pass = form_auth.cleaned_data.get('room_pass')
password2 = form_auth.cleaned_data.get('password2')
if room_pass != password2:
messages.error(request, 'Doesn\'t match')
return HttpResponse('error')
else:
# messages.success(request, 'match')
user = CustomUser.objects.get(username=user)
room = get_object_or_404(Room, slug=slug)
if user.has_perm('pass_perm', room):
return HttpResponseRedirect(Room.get_absolute_url(room))
else:
return HttpResponse('You don\'t have access to this page')
else:
form_auth = AuthRoomForm()
return render(request,'rooms/auth_join.html', {'form_auth':form_auth})
I mean maybe try to do something like that,what i should use istead HttpResponse and how to implement in the template
{% if form_auth.errors %}
{% for field in form_auth %}
{% for error in field.errors %}
<div class="ui red message">
{{error}}
</div>
{% endfor %}
{% endfor %}
{% endif %}

You template is showing all the form's errors. So you just need to make sure that the validation errors are added to the form, and that's not done by returning an HttpResponse with just an error string.
You have two options:
Preferred route is to perform all validation in your form AuthRoomForm, not in your view. The documentation explains all the ways to add custom validation to your form, most common is to use the clean() and clean_<fieldname>() methods.
If you really want to do this in your view, just use the form.add_error() method, e.g. form.add_error(ValidationError('You don\'t have access to this page')).
In both cases, if the form isn't valid, don't return HttpResponse(<error>). Just render() your template with the bound form, as shown here and in every starter Django tutorial about Django forms.

Related

Django restricting users from updating/deleting other users posts

views.py
#login_required(login_url='/login')
def updatepost(request,pk):
post = Post.objects.get(id=pk)
form = PostForm(instance=post)
if request.method =='POST':
form = PostForm(request.POST, request.FILES, instance=post)
if form.is_valid():
form.save()
return redirect ('mainpage')
context = {'form':form}
return render( request, 'postform.html', context )
postform.html
{% include 'main.html'%}
{% block content %}
{%if user.is_authenticated%}
{% if user.id == post.user.id%}
<div>
<form method="POST" action ="">
{% csrf_token %}
{{form.as_p}}
<input type="Submit" value ="Submit"/>
</form>
</div>
{%endif%}
{%endif%}
{% endblock content %}
I am trying to restrict user who is logged in - from updating , deleting other users posts.
However when I Try to use {% if user.id == post.user.id%} , the page becomes blank even for the user who is editing his own post. The same goes for deleting.
It works on mainpages - where posts are displayed (it hides edit and delete buttons).
What is the reason that the post is not showing inside the template ?
I don't understand that even {{post.user}} in postform.html does not appear , neither on deleteform etc. - why this data of objects of a post is not being sent to postform.html ?
You should change the context to access the post instance from your template.
context = {'form': form, 'post': post}
You can only access the context values from the templates. So pass the ones you want to use while you are returning a response.

Django's UserCreationForm's Errors isn't working?

few months ago i made a website where it worked but similar code this time isn't working! it returns :
ValueError at /registration/
The User could not be created because the data didn't validate.
this is my form.py in bottom:
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
my views:
from .form import CreateUserForm
def registrationPage(request):
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid:
form.save()
return redirect("login")
else:
form = CreateUserForm()
context = {"form": form}
return render(request, "store/registration.html", context)
in HTML previously i used :
{{form.errors}}
& it used to show me work on the page but not anymore
According to your comment above ("i want django to show the error messages"[if password is weak in example]), you should add this to your html page (instead than {{form.errors}}).
<div class="error-message">
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p style="font-size: 13px;">
{{ error|escape }}
</p>
{% endfor %}
{% endif %}
</div>
Form.non_field_errors()
This method returns the list of errors from Form.errors that aren’t associated with a particular field. This includes ValidationErrors that are raised in Form.clean() and errors added using Form.add_error(None, "...").
When this error you get then do this:
You must type strong password, which is provided by Django.
password validation rules:
At least 1 digit;
At least 1 uppercase character;
At least 1 lowercase character;
At least 1 special character;
for example:
Example#4089
This error will come while confirming your password, you must enter correct password in both the fields.
you will face this error if user is already exist.
you must check exists user while creating user, if user exist, this error will come.

django if user.is_authenticated not working but login user

my problem is that the login operation is done correctly and the session is set up correctly, but user.is_authenticated does not work.
The point is that it works when I log in through the admin, but not like this, what can I do to fix it?
my code :
views.py
class LoginView(View):
def get(self, request):
login_form = LoginForm()
context = {
'login_form': login_form
}
return render(request, 'account/login.html', context)
def post(self, request: HttpRequest):
login_form = LoginForm(request.POST)
if login_form.is_valid():
user_email = login_form.cleaned_data.get('email')
user_password = login_form.cleaned_data.get('password')
user: User = User.objects.filter(email__iexact=user_email).first()
if user is not None:
check_password = user.check_password(user_password)
if check_password:
login(request, user)
return redirect('home')
else:
login_form.add_error('password', 'password is not correct !')
else:
login_form.add_error('email', 'email dose not exists !')
context = {
'login_form': login_form
}
return render(request, 'account/login.html', context)
header_component.html
<div class="navbar__list">
<ul class="navbar__links">
{% for link in links %}
<li class="navbar__link">{{ link.name|capfirst }}</li>
{% endfor %}
{% if user.is_authenticated %}
<li class="navbar__link">welcome</li>
<li class="navbar__link">Log out</li>
{% else %}
<li class="navbar__link">Login</li>
<li class="navbar__link">Register</li>
{% endif %}
</ul>
</div>
{% if user.is_authenticated %} is deprecated.
Use this instead:
{% if request.user.is_authenticated %}
# Do something for authenticated users.
...
{% else %}
# Do something for anonymous users.
...
According to documentation:
Django uses sessions and middleware to hook the authentication
system into request objects. These provide a request.user
attribute on every request which represents the current user. If the
current user has not logged in, this attribute will be set to an
instance of AnonymousUser, otherwise it will be an instance of
User. You can tell them apart with is_authenticated as shown above.
Edit: Add documentation explanation.
I am writing this for friends who have this problem
The solution to this issue is that the user must be is_active equal to True to perform the login operation, otherwise the section
request.user.is_authenticated
Otherwise it does not work and does not enter the user

Without assigning 'action' value in html tag of django project still it render the page and submit the value to database, How?

urls.py
from django.contrib import admin
from django.urls import path
from poll import views
urlpatterns = [
path('', views.poll_home, name="poll_home"),
path('poll_details/<int:id>/', views.poll_details, name="poll_details"),
path('<int:id>/', views.poll, name='poll')
]
views.py
def poll(request, id=None):
if request.method == 'GET':
try:
question=Question.objects.get(id=id)
except:
raise Http404
return render(request, 'poll/poll.html',{'question':question})
if request.method == 'POST':
user_id=1
data=request.POST['choice']
ret = Answer.objects.create(user_id=user_id,choice_id = data)
if ret :
return HttpResponse('Your vote is done successfully.')
else:
return HttpResponse('Your vote is not done successfully.')
return render()
poll.html
{% extends 'employee/employee_home.html'%}
{% block content%}
<h1>Vote Page</h1>
<h3>{{ question.title}}</h3>
<form method="POST" action="">
{% csrf_token %}
{% if question%}
{% for choice in question.choices %}
<input type="radio" name="choice" value="{{ choice.id }}">
<label>{{ choice.text }}</label>
{% empty %}
<p>There is no choice available for this question</p>
{% endfor%}
<button type="submit">Vote</button>
{% else %}
<p>There is no choice available for this question</p>
{% endif%}
</form>
<h4><i>This question is created by {{question.created_by.first_name}}</i></h4>
{% endblock content%}
Even though I doesn't have mentions the action value in html page still it going to submit the data and successfully show the result
I want to understand how django knows the action path
This part causing the confusion:
if request.method == 'POST':
user_id = 1
data = request.POST['choice']
ret = Answer.objects.create(user_id=user_id, choice_id=data)
if ret:
return HttpResponse('Your vote is done successfully.')
else:
return HttpResponse('Your vote is not done successfully.')
return render()
The line leads to the object creation on every POST request: Answer.objects.create(user_id=user_id, choice_id=data), and the new object instance will be assigned to the ret variable which is always True that's why you're gettings successful message. The better workflow would be:
if request.method == 'POST':
try:
# do not hardcode user id,
# use user instance from the request
user = request.user
choice = request.POST['choice']
ret = Answer.objects.create(user=user.id, choice_id=choice)
return HttpResponse('Your vote is done successfully.')
except Exception:
return HttpResponse('Your vote is not done successfully.')
return render()
As I am writing both GET and POST methods in same definition of python so when I make a request with GET method it shows the poll.html page. As we are submitting the data to same page so need not to mention action property.

Display User Profile getting ERROR: 'AnonymousUser' object has no attribute '_meta'

I have a simple view that is suppose to check if there is post data,
if so update the user data using UserChangeForm. Else get the form
data of user and display.
Issue: AttributeError at /profile/edit 'AnonymousUser' object has no
attribute '_meta'
I think it might be this line in the edit_profile view
# Handles the get request - if no post info is submitted then get the form and display it on the edit profile page.
else:
form = UserChangeForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/profile_edit.html', args)
Not sure what. Here is the view.py edit_profile
def edit_profile(request):
# Handle post request - if the user submits a form change form details and pass the intance user
if request.method == 'POST':
form = UserChangeForm(request.POST, intance=request.user)
if form.is_valid():
form.save()
return redirect('accounts/profile')
# Handles the get request - if no post info is submitted then get the form and display it on the edit profile page.
else:
form = UserChangeForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/profile_edit.html', args)
profile_edit.html
{% extends 'base.html' %}
{% block head %}
<title>Profile</title>
{% endblock %}
{% block body %}
<div class="container">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save Changes</button>
</form>
</div>
{% endblock %}
You can't update an AnnonymousUser (that is special user class set for not logged in users). One solution of your problem is to disallow viewing this page by not authenticated user by decorating your view using login_required decorator.
You got error because there is not user logged in.
You can instead use try method.
In your code use if user.is_authenticated
if user.is_authenticated():
if request.method == 'POST':
form = UserChangeForm(request.POST, intance=request.user)
if form.is_valid():
form.save()
return redirect('accounts/profile')
# Handles the get request - if no post info is submitted then get the form and display it on the edit profile page.
else:
form = UserChangeForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/profile_edit.html', args)
else:
raise PermissionDenied

Categories

Resources