I have created a page for review form. All users can fill out the form, but only logged in users can submit the form. If users is not logged in, they will be redirected to the login page. After they login, they will be redirected to the profile page.
So the flow will be like this :
User fills out the form > click the submit > redirected to login page > user login and redirected to profile page (at the same time, the form they have filled in is automatically saved)
I want the form they have filled in automatically saved after they login. How to do that?
My idea is to create a session that saves the form temporarily, then save to database after they login. But I'm confused how to write the code
Can anyone explain a bit what a django session is like? and how to write code to handle this problem?
You can try something like,
1 User fills out the form and hits submit
2 in the POST view where you handle the form, use the "**is_authenticated**" function and,
a)if the user is authenticated you handle the form as usual...
b)else set the contents of the form into a session variable in the views and redirect to the login page like,
request.session['review_body'] = request.post.get(the_form_body_field)
3 as per what you've said, after login it goes to profile page and form is submitted...
a)so in views where you serve the profile page, check if the session variable containing form data's exist and has values
b)if yes, directly save the contents from your views and clear the session data
Related
The current flow for visitors with django-allauth is if the visitor fills in a form, if they are not already authenticated they are shown a login modal with option of facebook login or standard signup form, with the original form data being saved in ACCOUNT_SIGNUP_FORM_CLASS=SignupForm
class SignupForm(forms.Form):
def signup(self, request, user):
new_user = Profile()
new_user.user = user
new_user.save()
# if form data provided with signup save it.
model = self.cleaned_data['model']
if model:
# save the form
This works fine if the user signs up using the standard signup form, but if they signup using facebook social account the values from the form are now empty strings i.e. self.cleaned_data['model']. I assume the original request object is destoryed so the post data is lost? There also doesn't seem anyway to pass the form data to facebook and receive it back e.g.
<a title="{{provider.name}}" href="{% provider_login_url provider.id modal="1" process="login" next=request.path scope=scope auth_params=auth_params %}"
Is the only way to do what I want is to save the form data using local storage or the database then somehow assign it back to the visitor once registered and save it?
What I've gone with is changing the Facebook signup button to link to an intermediate view where I save the form data as session data and then redirect back to the allauth facebook login url.
I then extract the form data from the session in the signup method after the user has authenticated with facebook.
I am writing a web based application that has a same login form in every page,so when user submit login form data sent to '/login/' page that corresponde view to this url will check the data has submitted and if input data was incorrect app must back to previews view and on that view in login form i must write a error that indicate that user entered incorrect data,so my question is how can i send data from login view to previous view(like home) that user entered incorrect data?
You can use sessions ... specifically messages framework
example from docs:
messages.add_message(request, CRITICAL, 'A serious error occurred.')
and related question
Displaying Django Messages Framework Messages
In your login view, you use HttpResponseRedirect to send your user to your home view if the login is successful.
If the login is not successful, show the user the login form along with some error message that you can show the user if needed.
At the home view, you check if the user is logged in - if not, use HttpResponseRedirect to send them to the login view.
I'm aware that there is a context variable called "next" which allows you to specify the URL to redirect to after a page, which is commonly used when you want to redirect a user to a login page, then redirect them back to the page they were at before the login page once they've logged in.
In my views I've resorted to manually setting it via the URL such as redirecting to /login/?next=/someurl, but this isn't a clean way. I've tried googling and such, but there is surprisingly little information about it online.
How exactly do you set the context variable "next"? My site has a form that anyone can see, but only logged in users can submit. Right now if the user isn't logged in, they will get redirected to the login page with the "?next=/someurl/" attached to it so they get sent back to the original form once they log in.
However, from the login page there is a link to the sign up page for users who don't have an account, and I want to set "next" to be the original form page so that after they sign up they are redirected back to the original form. Any ideas or advice?
It sounds like you want to not simply use next for one redirect, but persist it across two redirects:
Some form page -> login -> signup -> Get back to some form
For the login page by itself, Django provides some automatic help for this (if you use the built-in auth views). But the second hop to the signup page requires some custom code explained below.
If you are using Django's built-in login view, and have created your own template for it, then Django will pass the current value of next to the template as a context variable called (appropriately) next. You can use that in the link to your sign-up page like this:
Sign me up!
Consequently, in the view you create to handle your user signup page, the value of next will be accessible as a GET param:
def signup(request):
if request.method == 'GET':
next = request.GET.get('next', None)
if next:
# Add it as a hidden input in your signup form
# Or re-append it as a GET param
# Or stick it in the user's session, which is
# what this example does:
request.session['next'] = next
Finally, in the same signup view, when you respond to the POSTed signup form, retrieve the next value in whichever way you chose to propogate it in the GET request, and redirect to it's value.
def signup(request):
....
# POST handling section
if signup_form.is_valid():
next = request.session.get('next', None)
if next:
# See caution note below!
return redirect(next)
Caution:
Be aware that you should check and sanitize the next value before you redirect to it after processing the signup form, to prevent browser-side tampering. For example, it's common to validate that the URL belongs to your own domain (if that's appropriate) and/or that Django's resolve function is able to successfully resolve it.
I have a form with csrf token that works.
There is also a button to upload a picture via ajax and put the url into a textarea of the first form on the same page. I have some js inplace to set the csrf value and the button also works fine.
If the user is logged in there is absolutely no problem when using first the button to insert the image url and then saving the form.
But when I have a visitor who is not logged in there is a problem: When he uploads a picture a new account is automatically created and the visitor is logged in without him doing anything.
while True:
try:
random_password = User.objects.make_random_password()
random_username = str(uuid.uuid1().hex)[:5]
new_temp_user = User.objects.create_user(random_username, password=random_password)
except IntegrityError:
pass
else:
new_user = authenticate(username=random_username,password=random_password)
login(request,new_user)
break
Since this is done via Ajax he doesn't notice any change to the website he is seeing. Only the url of the uploaded picture gets added to the first form. On the server side he is now a registered user, but he doesn't see it yet. Now when he submits the form the csrf validation fails. The form still has the csrf token in place, but somehow it became invalid.
I suspect that the login process has some influence over the csrf token. Any ideas what I may do about it?
EDIT: I checked some more and it seems that the problem is due to the login. Every login seems to change the csrf value. Now when the user gets a login over ajax the token in the form doesn't update. What may be the best way to update it?
The csrf token is rotated when the user logs in. This was added as a security measure in Django 1.5.2 (release notes).
After the ajax request, you might be able to fetch the new csrf token from the cookie, and update the form in the DOM. Alternatively, you could refresh the page after the user is logged in.
I have a login form. When login button is pressed user's homepage is displayed. But pressing browser's back button takes control back to login form.
I am using django development server.
I have tried inserting meta tags to prevent cache and django #no-cache
But it doesnt work out
The default django login page can be viewed when logged in. You could decorate the login view function and redirect the user if already logged in.
response = <the_way_you_create_response> (ie direct_to_template, HttpResponse)
response['Cache-Control'] = 'no-cache, no-store'
return response
and of course you need to check request.user.is_authenticated() in the view (and do the redirect if value is True)
In your login page you need to check if a users session exists and if it does then you should redirect the user to his homepage.
However, this can't be done with a HTML page so you need to use some kinda server side scripting language(PHP, ASP, JSP Etc) for your login page.