How can I display content side-wide (on every page) based on if the user is logged in or not? I have a sidebar area defined in my base.html which is either populated with login/register forms (if the user is not logged in) or a dashboard (if the user is logged in).
How can I make this universal to every single web page on my site? Do I have to manually check the user each time a new view is called and pass a user variable to my render_to_response()? There's got to be a simpler way.
I don't think there are a system wide solution if I understood you right. You have to verify each page based on whether the user is authenticated or not.
In the template you add the following code to see whether the user is a valid and authenticated. And you have to do so for each template with user level contents.
{% if user.is_authenticated %}
... html stuff ...
{% endif %}
Another idea maybe is to use decoration #login_required. However you would still need to add it to each view with user level contents.
Related
i want to get a value in an input to a django views, this is not a form as i am not trying to submit any form, i just need the value that is in the input field
this is the html template
<input readonly name="ref_code" type="text" value="{{ request.user.profile.recommended_by.profile.code }}">
this is my django views
code = str(request.GET.get('ref_code'))
print("This is the code:" + code)
It keep printing This is the code: None
NOTE: i have also tried using request.POST.get("ref_code") it did not still work
What might be the issue?
You definitely need something like a form.
So, let's walk you step by step on how your code works.
First, there is a view which prepares the data to be rendered with the template. This view responds to the first request from the user's browser and returns the rendered template as a static html page to the user.
Second, user's browser displays received html page to the user.
Third, user enters something into the input field.
At this stage the data user has entered is still on their side in their browser.
At this point you have two options:
Use a form to let user send the data to some view on the server which will then process the received data.
Use JavaScript to capture the entered data and send it to the server using an AJAX request.
I guess, you would like to use the second option in this case.
I'd recommend to read a guide on AJAX basics. The Ajax guide on MDN is a good place to start.
In my project, I'd like to split pages between a side menu and a content page.
I'd like to show a sidemenu which is different for user types (there are 5 user types, so there will be 5 sidemenus). But sometimes, the content page to display can be the same for these 5 user types.
I was looking for a "pattern" to handle this, I thought about one, but never seen it in another project. I'd like you to tell me if it's a good or bad practice:
1 URI for all user types (eg. /myapp/display_home)
In views.py, 1 view for all user types. Into the view, I try to know if the user is logged in, and then which type of user we are dealing with. Then, redirect to the HTML, passing in context a variable containing the user type.
In the end, in the template, something like this:
Example of template:
{% if user_type == "anonymous" %}
<!-- display anonymous sidemenu here -->
{% elif user_type == "landlord" %}
<!-- display landlord sidemenu here -->
{% endif %}
<-- Here is the same content for all user types -->
Do you have any suggestion? another pattern to propose?
Check this answer for discussion on user.is_authenticated. You can also check within the view to see who the user is (see here) and modify the context being sent to the template accordingly. Another option would be to modify your view to simply show different types of users different templates.
Lots of ways to accomplish this, not sure if there's a "correct" one.
Your comment made me realize that this is exactly what the Groups feature of the auth package is for. You can assign users to groups, query whether they're a member of the group, and then show content based on that. I apologize that I don't have time to write out sample code, but there's tons of stuff here on SO about it; hopefully that's a good starting point for you.
I don't know if it is good style. But you could use
{% include user_type_sidemenu_template with arg1=... %}
in your template and provide different templates for the sidemenu for each user_type. You can then set the template variable user_type_sidemenu_template to the corresponding template name in your view.
So I have my django project which includes a HTML page that shows a list and a submit button.
I want to use the submit button to send the selected item ID to the server and than use it.
That`s my code :
<form>
<select>
{% for item in list %}
<option value={{item.name}}>{{ item.name }}</option>
{% endfor %}
</select>
<input type="submit"/>
</form>
The things I want to know are :
What to write in the action of the form so it will only reload the page.
How to enter the form data into a view.
As i understand, you want to take the value on your select and do something with it in the server.
I would advise you to read the documentation, as it is pretty detailed about what you need to know to work with forms. You should also read a little about forms, as you are missing a couple details.
Now, the action must point to one of your urls. Your url must be pointing to a view and in your view, if everything is ok, you should be getting a request object.
Depending on your post method, you have a python dictionary in request.GET or request.POST, filled with the values in your form.
That is assuming you are using your form created from scratch. In django you can use the Form class, which creates the html (or lets you create it, but giving you some constraints), validates the form, saves the form to a model (in the case it is a ModelForm). It is a valuable class for me and prefer it over working with raw html.
Also, assuming you haven't, i strongly advice you to go through the getting started. Even if it keeps things basic, it does a good job at introducing core django modules.
The Django framework easily handles redirecting when a user fails to log in properly. However, this redirection goes to a separate login page. I can set the template to be the same as the page I logged in on, but none of my other objects exist in the new page.
For example, I have a front page that shows a bunch of news articles. On the sidebar is a login form. When the user logs in, but fails to authenticate, I would like it to return to the front page and preserve all the news articles that show. As of current, none of the news articles show up.
How can I fix this problem? Any help is appreciated.
Edit: Remember that I have dynamic content that is being displayed, and I would like it to still display! Futhermore, the main page is not the only place a user can log in. The sidebar never changes, so the user can potentially log in from any page on the site, and all of the content on that page exactly as it was still needs to be displayed upon failure to log in.
Do you want to redirect to the referring page on failed login?
... authentication code above
if user.is_authenticated():
#show success view
else:
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('index'))
you might want to check that referring page url is set correctly, otherwise set it to default url (assuming that your default url is named "index").
Use an <IFRAME> in the sidebar to
call the login view -- all postbacks
will happen within the iframe, so
your page stays intact. If the
visitor logs in successfully, you
can use javascript to redirect the
parent page to some other URL
Use AJAX to post the login form --
acheives the same effect as (1), but
it means your visitors will need to
have javascript-enabled browsers
I personally prefer to have the login on a separate page. If you're only worried about your visitors losing their current page (and not say, bound by a fussy client), you can have the login show up in a lightbox. I've used all three approaches in the past, and I'd be happy to post some code samples if you're interested.
This is because redirecting to a view misses the original context you use to render the page in the first place.
You are missing just a simple logic here. You are trying to render the same template again, but with no news_article list.
I suppose (in the first place), you are rendering the template which shows you Articles as well as login form, by sending two things 1. Login Form, and 2. Articles List.
But secondly, when user fails to authenticate, you are not passing the same things again. Pass those variables again as context (you can also add error message if your form is not handling error messages).
if user.is_authenticated():
#show success view
else:
return render_to_response('same_template.html', {
'error_msg': 'Username or password you provided was incorrect',
'news_articles': NewsArticles.objects.all()[:3],
'login_form': LoginForm(request.POST);
})
Edit: The reality is that, a context is used to render a template, and it's the complete responsibility of that template, what it wants to pass in further navigation. And as I see, if you are not passing something further, you are not getting it further.
If you want some automated context, develop your own context processor, something like the auth-context-processor, which automatically adds like 'user', always available to the template.
And by the way, you are going to miss that kind of context anyway, even if login is authenticated. So if that particular context is really important, either try sending the primary keys of articles along with the login form submit, or store that in global (ugliest thing ever) or just reconsider and separate the flow (good thing, I feel).
User should be redirected to the Login page after registration and after logout. In both cases there must be a message displayed indicating relevant messages.
Using the django.contrib.auth.views.login how do I send these {{ info }} messages.
A possible option would be to copy the auth.views to new registration module and include all essential stuff. But that doesn't seem DRY enough.
What is the best approach.
Update: Question elaboration:
For normal cases when you want to indicate to some user the response of an action you can use
request.user.message_set.create()
This creates a message that is displayed in one of the templates and automatically deletes.
However this message system only works for logged in users who continue to have same session id. In the case of registration, the user is not authenticated and in the case of logout since the session changes, this system cannot be used.
Add to that, the built in login and logout functions from django.contrib.auth.views return a 'HttpResponseRedirect' which make it impossible to add another variable to the template.
I tried setting things on the request object itself
request.info='Registered'
and check this in a different view
try:
info = request.info:
del request.info
except:
info = ''
#later
render_to_response('app/file',{'info':info})
Even this didn't work.
Clearly I can define a registered.html and add this static message there, but I was being lazy to write another template and trying to implement it DRY.
I realized that the cases were different for "registered" message and "logged out" message. And the DRY approach I used, I shall write as an answer.
If the messages are static you can use your own templates for those views:
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}
From the docs.
I think the best solution to this problem is to use a "flash"-type session-based messaging system. There are several floating around: django-flash seems really nice, I use django-session-messages which is very simple. Hopefully by the time we get to Django 1.2 this'll be baked-in.
You have Request Context Processors to add this kind of information to the context of every template that gets rendered.
This is the "zero impact" way to do this kind of thing. You don't update any view functions, so it meets some definitions of DRY.
See http://docs.djangoproject.com/en/dev/ref/templates/api/#id1
First, write your own login.html template.
Second, write your own context function to provide any additional information that must be inserted into the template.
Third, update settings to addy your context processor to the TEMPLATE_CONTEXT_PROCESSORS setting.