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

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

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.

How can I get information about the logged-in user in a Django application?

How can I get information about the logged-in user in a Django application?
What I want to do is get the user information from Logged-in user and put additional information and store in a database(models.py).
So in views.py:
def registerView(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login_url')
else:
form = UserCreationForm()
return render(request, 'main/register.html',{'form':form})
here how do I grab the users information
There are several ways for get information from authenticated user in django
1) In the view
You can use request.user like this :
def test_user(request):
if request.user.is_authenticated:
# Do some stuff with the user = request.user
my_user = request.user
my_user.email = 'demo_user#yopmail.com'
my_user.save()
else:
# The user is not authenticated
# You can't do anything i guess
return render(request, 'template/logged_in_user.html')
2) In the template
<!-- Show something to the authenticated user -->
{% if user.is_authenticated %}
<h1> Hi {{ user.name }} </h1>
{% else %}
<!-- Show something to the guess user -->
<h1> Hi Guess ! </h1>
{% endif %}

Django checkout not accessible: Page not found (404)

I'm trying to develop an e-commerce site with Django. So I'm at this point where, users can add items to their cart, but when I try to proceed to checkout, for some reason, my checkout form is not displayed rather, it says:
Page not found (404)
I made sure that I have registered my models, and ran migrations.
What is the problem?
My views.py:
#login_required
def checkout(request):
address_form = UserAddressForm(request.POST or None)
if address_form.is_valid():
new_address = address_form.save(commit= False)
new_address.user = request.user
new_address.save()
else:
raise Http404
print(form.errors)
context = {"address_form": address_form}
template = "orders/checkout.html"
return render(request, template, context)
My checkout.html:
<form method="POST" action=''>
{% csrf_token %}
<fieldset class="form-group">
{{ address_form|crispy }}
</fieldset>
<div class="form-group">
<input type="submit" class="btn btn-outline-dark" value="Place Order"/>
</div>
</form>
My urls.py:
from orders import views as orders_views
path('checkout/', orders_views.checkout, name='checkout'),
You've implemented GET request handling incorrectly, for reference see this example from the docs. In your case form was always invalid because in case of GET request it was initialized with none. However you don't even have to validate empty form on GET request.
Your code updated:
#login_required
def checkout(request):
if request.method == 'POST':
address_form = UserAddressForm(request.POST)
if address_form.is_valid():
new_address = address_form.save(commit= False)
new_address.user = request.user
new_address.save()
return # TODO : return what?
else:
# otherwise (if GET request) we get here
address_form = UserAddressForm()
context = {"address_form": address_form}
return render(request, "orders/checkout.html", context)
And you need to specify what is supposed to happen when the form is valid: redirect for example.

Avoiding page refresh when a form is used in Django

I have a very basic Django view:
def myview(request):
if request.method == 'POST':
if 'button1' in request.POST:
form1 = form = myForm(request.POST)
# check whether it's valid:
if form.is_valid():
profile = form.save()
profile.user = request.user
profile.save()
messages.success(request, f"Success")
return HttpResponseRedirect(request.path_info)
else:
form = myForm()
return render(request,
"main/mytemplate.html",
context={"form":form})
And its template:
<form method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form %}
<button name="button1" type="submit" class="btn btn-primary">SUBMIT</button>
</form>
Everything works here, when this form is used, some data is saved on my DB. What i would like to change, though, is the page reload after the form is used.
When the Submit button is hit, the page will be refreshed. Since it makes the navigation way slower, i would like to have the view not refreshing the page each time the form is used.
Is it possible to accomplish this in Django? For example, instead of refreshing the page, i would like to only load part of it, or to have a 'Reload' icon while the view is doing its work.
I'm pretty new to Ajax, so i don't know how to get started on this.

Django form requires resubmission

I have a simple form in Django, and in my template I want to display each individual object for the whole queryset which I am saving the form to. The error I am getting is that my form does not seem to submit on the first attempt. Only when I click the submit button, manually refresh the page and then 'confirm form resubmission' do I see my updated queryset objects displayed in the template.
I am saving my form like this in my views:
exercise_name = ExerciseName.objects.all()
if request.method == 'POST':
form = ExerciseNameForm(request.POST)
if form.is_valid():
form.save(commit=True)
else:
form = ExerciseNameForm()
and passing the queryset to the template through the following context:
{ 'exercise_name': exercise_name }
and iterating through it like
{% for exercise_title in exercise_name %}
#content displaying each iteration
{% endfor %}
with my form to update it like:
<div>
<form method = "POST">{% csrf_token %}
{{form.as_p}}
<button type="submit" class="save btn btn-default">Save</button>
</form>
</div>
I am not sure why it is making me refresh the page and resubmit the form again in order to see the updated queryset after submitting the form?
You should be doing something like this:
if request.method == 'POST':
form = ExerciseNameForm(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponse("data submitted successfully")
else:
return render(request, "your_template.html", {'form':form})
else:
form = ExerciseNameForm()
return render(request, "your_template.html", {'form':form})

Categories

Resources