Rename reference to Django messages in templates? - python

I'm using Django's messaging framework to alert a user that a message was sent successfully. By default, you display a Django message in a template using {{ messages }}. I want to avoid any possibility of confusion by renaming the variable to refer to Django's system message as something like {{ system_message }}, leaving {{ message }} free for referring to user messages.
I've tried doing something like
from django.contrib import messages as system_message
but renaming it in this context doesn't carry through to my template. Any suggestions?

Messages isn't a template tag but a template context variable provided by the "django.contrib.messages.context_processors.messages" processor. I think the best way to rename it is simply replacing django's context processor with your own version, e.g:
from django.contrib.messages.api import get_messages
def messages(request):
"""
Returns a lazy 'messages' context variable.
"""
return {'your_name_space': get_messages(request)}

Related

Django - add context to request to be used by the view

Using Django I want to implement some middleware that will calculate some context that is to be used by the view itself.
For example, I have a middleware that looks at the request, and adds the user's permissions to the request, or some user configuration. The view looks at these permissions and decides how to handle the request using it.
This saves the need for multiple views (and multiple parts within the view) to query for this information.
I'm wondering what is the correct way to do that. One option is to just add request.user_permissions=... directly on the request. But is there some documented and expected way to do that?
There's no real documented way to do that, but Middleware is the correct place to do it and just adding properties to the request object is also the correct way.
You can confirm this, because Django is already doing it:
LocaleMiddelware
AuthenticationMiddleware
RemoteUserMiddleware
CurrentSiteMiddleware
SessionMiddleware
So just pick whatever is the most convenient data structure for your use case and tack that on to the request object.
This is not a perfect answer but at my experience I use this code. Every permission is saved in a boolean value which is true or false. You can access it in a html template like.
{% if request.user.is_admin %}
"Your code here"
{% else %}
"Your code here"
{% endif %}
and to send extra context you should create and pass an dicionary and pass it as as an argument to the render method from the view.
For eg:
def view(request, slug):
context = {'administrator':True}
blog_post = get_object_or_404(BlogPost, slug=slug)
context['blog_post'] = blog_post
return render(request, 'blog/detail_blog.html', context)
and access it like
{% if context.administrator %}
"Your code here"
{% else %}
"Your code here"
{% endif %}
I believe, since your middleware will calculate context, it should be implemented as context processor.
https://docs.djangoproject.com/en/3.1/ref/templates/api/#using-requestcontext
https://docs.djangoproject.com/en/3.1/ref/templates/api/#writing-your-own-context-processors

how to set access control or privilege for Django models and views?

i create a model for website/ frontend . i have 3 types of users. only 1 type i want to see the frontend model. how to create a dynamic access control for the django frontends. please give some solutuion or suggest a plugin. Thanks for solution in advance.
You can do this on the template or views side.
Assuming your preferred user type is 'student', you do this:
Template
{% if user.is_authenticated and user.is_student %}
*content*
{% endif %}
Or this:
Views
Assuming you want to restrict the details of a blog post to only students, you need to create a condition right after defining the 'post_detail_view' view function.
def post_detail_view(request):
if not request.user.is_student:
**do something (eg. raise 404 or httpresponse or redirect)**
**code for this view goes here**
Declaring the restriction in the view allows you to do more than just restrict the content. You can raise a 404 error, redirect the unauthorized user and more. The template solution simply lets you restrict the content.
I hope this solves your problem.

Finding the source of Django login page message

I have created a working Django application. I am using django-allauth for implementing social-account authentication.
Now, suppose I am logged-in inside my application using an e-mail id whose user does not have a staff access and, if I open admin login page directly, the admin login page is displayed as follows:
My question is: how can I stop Django from displaying the message "Successfully signed in as ... "? Where is the source of this message present?
The Successfully signed in message is a message from django-allauth. It uses the messages framework.
I suggest that you add the template code to display messages to your base template. That way, the message will be displayed immediately after you have logged in, rather than when you go directly to the admin login (which does include the template code to display messages).
The text you are referring to (You are authenticated as ...) can be found in this template:
python3.6/site-packages/django/contrib/admin/templates/admin/login.html
You can override this template to remove the messsage. For example, look into this question for how to override djangos default templates.
To override this you need to inherit the template by {% extends "admin/login.html" %}
Then you need to override the block with the name.
{% blocktrans trimmed %} You are authenticated as {{ username }}, but are not authorized to access this page. Would you like to login to a different account? {% endblocktrans %}
Now you can customize this particular line and then point your function to load your custom html file instead of the standard admin ones or you can directly edit the login.html in your django package(Not a good idea). To know where it is fetching from you can do the following...
$python
>>>import sys
>>>sys.path = sys.path[1:]
>>>import django
>>>print(django.__path__)
And then go into contrib\admin\templates\admin and edit the login.html manually.

View all Object in Django Template

In this django function
def request(request):
args = {"name": "name", 'message': "message"}
return render(request, 'request.html', args)
the template will get {{name}} and {{message}} variable...
But apart from these two variable one can also access {{user}} and {{LANGUAGES}} object on template which are set in RequestContext by middleware.
Is there a way to displayed/render every object/variable that are sent to template either by my custom response or by any middleware like IP Address of requesting client, and other information.
You can get all variables and obj using debug
{% debug %}
If you want to print this vars for debugging only, try django debug toolbar
You can use the debug tag:
{% debug %}

How to send a session message to an anonymous user in a Django site?

I often show messages about user actions to logged in users in my Django app views using:
request.user.message_set.create("message to user")
How could I do the same for anonymous (not logged in) users? There is no request.user for anonymous users, but the Django documentation says that using the "session" middleware you can do the same thing as the above code. The Django documentation that links to the session middleware claims it is possible, but I couldn't find how to do it from the session documentation.
This is what I do, using context processors:
project/application/context.py (check for messages and add them to the context):
def messages(request):
messages = {}
if 'message' in request.session:
message_type = request.session.get('message_type', 'error')
messages = {'message': request.session['message'],
'message_type': message_type}
del request.session['message']
if 'message_type' in request.session:
del request.session['message_type']
return messages
project/settings.py (add the context to the TEMPLATE_CONTEXT_PROCESSORS):
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request",
"django.core.context_processors.debug",
"django.core.context_processors.media",
"django.core.context_processors.auth",
"project.application.context.messages",
)
With the above the function messages will be called on every request and whatever it returns will be added to the template's context. With this in place, if I want to give a user a message, I can do this:
def my_view(request):
if someCondition:
request.session['message'] = 'Some Error Message'
Finally, in a template you can just check if there are errors to display:
{% if message %}
<div id="system_message" class="{{ message_type }}">
{{ message }}
</div>
{% endif %}
The message type is just used to style depending on what it is ("error","notice","success") and the way that this is setup you can only add 1 message at a time for a user, but that is all I really ever need so it works for me. It could be easily changed to allow for multiple messages and such.
See http://code.google.com/p/django-session-messages/ until the patch that enables session based messages lands in Django tree (as I saw recently, it's marked for 1.2, so no hope for quick addition...).
Another project with similar functionality is Django Flash (http://djangoflash.destaquenet.com/).
Store the data directly in the session, which is a dict-like object. Then in the view/template, check for the value.
More information here:
http://docs.djangoproject.com/en/dev/topics/http/sessions/#using-sessions-in-views
You could also create a middleware class to check for the session object on each request, and do your build up/tear down there.

Categories

Resources