Django, updating a user profile with a ModelForm - python

I'm trying to display a simple ModelForm for a user's profile and allow the user to update it. The problem here is that my logic is somehow flawed, and after a successful form.save() call, the old values show on the page. It isn't until a refresh that the appropriate value is shown. What is wrong here?
#login_required
def user_profile(request):
success = False
user = User.objects.get(pk=request.user.id)
upform = UserProfileForm(instance=user.get_profile())
if request.method == 'POST':
userprofile = UserProfileForm(request.POST, instance=user.get_profile())
if userprofile.is_valid():
up = userprofile.save(commit=False)
up.user = request.user
up.save()
success = True
return render_to_response('profile/index.html',
locals(), context_instance=RequestContext(request))
I'm just looking to update an existing profile, not add a new one.

Try this:
#login_required
def user_profile(request):
success = False
user = User.objects.get(pk=request.user.id)
if request.method == 'POST':
upform = UserProfileForm(request.POST, instance=user.get_profile())
if upform.is_valid():
up = upform.save(commit=False)
up.user = request.user
up.save()
success = True
else:
upform = UserProfileForm(instance=user.get_profile())
return render_to_response('profile/index.html',
locals(), context_instance=RequestContext(request))

You could also use a generic view:
from django.views.generic.create_update import update_object
#login_required
def user_profile(request):
return update_object(request,
form_class=UserProfileForm,
object_id=request.user.get_profile().id,
template_name='profile/index.html')

Related

How to block page access to other logged in user in django?

I am trying to block logged in user to access other user update profile page.
My situation:
Suppose Person A is logged in to his profile and he know other user update profile URl. In this situation he can simple getting access of the update profile url of other user.
So , here i want to limit this restriction only to the same logged in user to update their profile only.
this is my code for updating profiles:
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if request.method == "POST":
form = UpdateProfileForm(request.POST, request.FILES, instance=user)
if form.is_valid():
profile_pic = form.cleaned_data['profile_pic']
form.profile_pic = profile_pic
form.save()
messages.success(request,"Data Updated successfully")
return HttpResponseRedirect(reverse('updateaddress', args=(request.user.profile.slug,)))
else:
messages.error(request, "Please check all fields are valid")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
form = UpdateProfileForm(instance=user)
context = {
'user':user,
'form':form,
}
return render(request, "authentication/register/update/profile.html",context)
urls.py
path("<slug:slug>/update-profile/", UpdateProfile, name="updateprofile"),
You can just do like this:
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if user.id == request.user.id:
# do something if the id of user you get from the slug matches the actual user id
if request.method == "POST":
form = UpdateProfileForm(request.POST, request.FILES, instance=user)
if form.is_valid():
# yada yada yada
You can compare the user object like below
#login_required
def UpdateProfile(request, slug):
user = Profile.objects.get(slug=slug)
if user != request.user:
message.info("You can't update the other user profile")
return
As described here in django documents :-
https://docs.djangoproject.com/en/4.0/topics/db/queries/#comparing-objects
You can try something like this in as a decorator
def verify_user_profile(view_func):
def wrapper_func(request, *args, **Kwargs):
user = Profile.objects.get(slug=args[0])
if user != request.user:
return
else:
return view_func(request, *args, **Kwargs)
return wrapper_func
View call will be :-
#verify_user_profile
#login_required
def UpdateProfile(request, slug):
...
...

when i refresh the page the form data automatically adding due to GET method when i remove it it show doesn't return httpresponse obj

how can i use is_valid() with POST method to get inputs from user
my views.py i also use return redirect() and HttpResponseRedirect() but it doesn't work
#login_required
def about(request):
data= userdata.objects.all()
form=student(request.POST)
if request.method =='POST' or 'GET':
if form.is_valid():
name = request.POST.get('name')
email= request.POST.get('email')
password =request.POST.get('password')
fm = userdata(name=name,email=email,password=password)
fm.save()
form =student()
else:
form=student()
return render(request,'about.html',{'form':form ,'data':data})
try the code below
#login_required
def about(request):
# i think you don't need 'data' and thus pass it in the context with 'form'
# data= userdata.objects.all()
if request.method =='POST': # POST request
form=student(request.POST)
if form.is_valid():
name = request.POST.get('name')
email= request.POST.get('email')
password = request.POST.get('password')
fm = userdata(name=name,email=email,password=password)
fm.save()
# Add flash message and then redirect
messages.success(request, 'SUCCESS !')
return redirect(reverse_lazy('home'))
else:
messages.error(request, 'Please correct the errors below.')
# if 'form.is_valid()' return false you will get all errors in 'form.errors' bag
else: # GET request
form=student()
return render(request,'about.html',{'form':form})
refer to :
https://docs.djangoproject.com/fr/3.1/topics/forms/#the-view
https://www.django-antipatterns.com/antipatterns/rendering_content_after_a_successful_post_request.html

Django: How to get a users coordinates (latitude, longitude) in a view?

I need to be able to check the user's location before determining where their redirect will be sent. Is there an easy way to do this in Django/Python?
views.py
#login_required
def update(request):
if users coords in range(....):
form = UpdateForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
update = form.save(commit=False)
update.user = request.user
update.save()
value = form.cleaned_data['update']
return redirect('main-home')
return render(request, "main/update.html", {'form': form})
else:
return render(request, "main/error.html")
Try
from django.contrib.gis.utils import GeoIP
g = GeoIP()
lat,lng = g.lat_lon(user_ip)

How to write a Django message into your views code

I'm reading the documentation on how to display a message to the user with Django messages. It says that in order to add a message in your views to call:
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
I'm not sure where to put the second the second line, this is my view:
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
ID = post.id_text
return HttpResponse('Thank you')
else:
return HttpResponse('That text is invalid')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
I want the message to appear and thank the user for signing up and display their input as well.
Bearing, in mind that it's customary to redirect to a success url on valid form submission, your code ought to look like this:
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
ID = post.id_text
messages.add_message(request, messages.INFO, 'Hello world.')
return HttpResponseRedirect('/thank-you-page/')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
note that this also results in the user being told why exactly his form is invalid (assuming that you have set up the template propertly). It's always good to say what the problem is rather than to say there is a problem.
You can put the second line in view with example:
def contact(request):
if request.method == 'POST':
name = request.POST.get('name')
email = request.POST.get('email')
password = request.POST.get('password')
textarea = request.POST.get('textarea')
contact = Contact(name = name,email = email,password = password,textarea = textarea,date=datetime.today())
contact.save()
messages.success(request, 'Form has submitted')
return render(request,"contact.html")

How can I get the id of the particular modelform?

I am new to Django. I am just learning to use forms and modelforms. Here I used modelforms to get two charfields(username and password) and saving it. What I wanted to do is to get the model id of that username. Below is the code. But I can't get the id.
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
from reg.models import registration, registrationform
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
def registration(request):
if request.method == 'POST':
form = registrationform(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
p = registration.objects.all()
for loop in p:
if loop.username == username:
id = loop.id
return HttpResponseRedirect(reverse('reg.views.thanks', args=(id)))
else:
form = registrationform()
return render_to_response('registration.html', {'form' : form}, context_instance=RequestContext(request))
def thanks(request, id):
p = get_object_or_404(registration, pk=id)
return render_to_response('thanks.html', {'reg': p)
One more question. What is the model field for password?
Thanks.
if request.method == 'POST':
form = registrationform(request.POST)
if form.is_valid():
data =form.save()
#...
id = data.id
#...
return HttpResponseRedirect(reverse('reg.views.thanks', args=(id)))
user = form.save(commit=False)
user.first_name = u'First name'
user.last_name = u'Last name'
user.save()
For password use password1 field
Please could you paste your urls.py?
I recently had a problem almost exactly the same as this - it was just a typo there, I had the wrong value in in second field of the url function:
url(r'^people/thanks/(?P<person_id>\d+)$', 'people.views.thanks'),
Should have been:
url(r'^people/thanks/(?P<person_id>\d+)$', 'people.views.new'),
How about changing your registration function to this:
def registration(request):
if request.method == 'POST':
form = registrationform(request.POST)
if form.is_valid():
userdetails = form.save()
user = userdetails.username
val = registration.objects.get(username = user)
return HttpResponseRedirect(reverse('reg.views.thanks', args=(val.id)))
else:
form = registrationform()
return render_to_response('registration.html', {'form' : form}, context_instance=RequestContext(request))
I suggest you read this: https://docs.djangoproject.com/en/dev/topics/forms/modelforms/

Categories

Resources