I need to display a message right after I open model admin page, is there a way? I know how to show it after save, but didn't find a way to show it on open.
You can use Django Messages Framework for that.
from django.contrib import messages
class MyAdminSite(AdminSite):
def each_context(self, request):
messages.add_message(request, messages.INFO, 'Hello world.')
return super().each_context(request)
Messages more here:
https://docs.djangoproject.com/en/4.1/ref/contrib/messages/#adding-a-message
AdminSite more here:
https://docs.djangoproject.com/en/4.1/ref/contrib/admin/#adminsite-objects
Related
When I login to django as a superuser, if an object of some model or the a field of the last object in that model doesn't exist or isn't set, how would I redirect to the creation of that model? And don't let me access the WebApp unless it's made?
I'm guessing there's a function to be run whenever a superuser logs in and check for an object or a field in the last object. I just don't know how to make this function and where to put it.
EDIT: Really sorry, I didn't elaborate my question further.
- I want to check for the existence of the object WHEN a superuser logs in to the webapp, not when they click on a model from the index. An object NEEDS to exist, that's why when it doesn't exist and a superuser logs in, they are to be taken to add form and not allowed to use the rest of the site until an object exists. So when someone logs in to the the Django Administration Site, I want to run a function that checks for the existence of that model and redirect or not, accordingly.
Thank you for your time reading this.
You can use a signal to run a function after the point a user logs in
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver
#receiver(user_logged_in)
def superuser_login(sender, user, request, **kwargs):
if user.is_superuser:
# Do stuff here
In your admin, you can override change_view with something like this:
class MyModelAdmin(admin.ModelAdmin):
... your admin declaration
def change_view(self, request, object_id, form_url='', extra_context=None):
try:
MyModel.object.pk(pk=object_id)
return super().change_view(request, object_id, form_url=form_url, extra_context=extra_context):
except MyModel.DoesNotExist:
return redirect('admin:yourapp_yourmodel_add')
It's not sql optimized as _changeform_view will fectch your instance agin, but it's the simplest solution.
I want to create a notification to django admin whenever a category is added in database. The admin should then click the boolean field and publish the category.
You could override the save() method on the Categry model - here is some sample basic code...
class Category(models.Model):
def save(self, *args, **kwargs):
if not self.pk:
#no pk so it is new
try:
send_mail('Subject here', 'Here is the message.', 'from#example.com',
['superuser#mail.com'], fail_silently=True)
except:
# do something a bit more elaborate here, like logging
pass
else:
#do something if it is an update or...
pass
super(Category, self).save(*args, **kwargs)
T go this route, just remember to import the send_mail functionality...
from django.core.mail import send_mail
Also, you could get the super users on the fly from the db - or import from the settings file - I have it hardcoded as an example.
EDIT: See Brandon's comment regarding post_save. That is probably a better solution, albeit slightly more advanced. If you don't want to go that route, please wrap the email logic in a try/except block to avoid something secondary like the email failing from blowing up your save.
When you save something via django admin you will get this bootstrap alert bar at the top of your page saying "save" or "please correct errors". How do I pass something in get/post parameters to be displayed in such bar?
You're looking for Django's Messaging Framework.
Here's some code from the docs:
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
# Shortcut methods
messages.debug(request, '%s SQL statements were executed.' % count)
messages.info(request, 'Three credits remain in your account.')
messages.success(request, 'Profile details updated.')
messages.warning(request, 'Your account expires in three days.')
messages.error(request, 'Document deleted.')
I have a django project in which there is a UserProfile having a OneToOne to the User model. It uses django-allauth for registration.
I am accepting registration via account and social account. Upon signing up, i want the user to be redirected to a page to create the UserProfile for that user account.
How could i do that ?
I have read, there is 1 signal called user_signed_up, can it be used to redirect the user to certain page ? I tried this code below, but it doesn't redirect me to the page i wanted.
#receiver(user_signed_up, dispatch_uid="some.unique.string.id.for.allauth.user_signed_up")
def do_stuff_after_sign_up(sender, **kwargs):
request = kwargs['request']
user = kwargs['user']
return redirect ('/test/')
any help will be greatly appreciated. thanks :)
I know its late but I hope future readers would find it helpful. :)
You need to raise an ImmediateHttpResponse like this:
from allauth.exceptions import ImmediateHttpResponse
from django.shortcuts import render
#receiver(user_signed_up, dispatch_uid="some.unique.string.id.for.allauth.user_signed_up")
def do_stuff_after_sign_up(sender, **kwargs):
request = kwargs['request']
user = kwargs['user']
raise ImmediateHttpResponse(render(request, 'you_custom_profile.html', {'user': user}))
I've added this decorator to one of my views
#permission_required('codename')
When a user visits that page and doesn't have the required permissions, he is redirected the login page, but it doesn't really tell him why he's been redirected there. Worse yet, if he logs in, and still doesn't have the permissions, he's going to be completely clueless as to why he can't access that page!
Isn't there a way I can tap into the messages framework and post an error at the same time?
Not sure what version of Django you are using, but in Django 1.4 and higher you can use:
from django.contrib.auth.decorators import permission_required
#permission_required('app.permission',raise_exception=True)
def myView(request):
#your view code
This will raise a 403 exception and if you have a 403.html page at the base of your template folder it will server this out.
If you are using class based views:
from django.views.generic.base import View
from django.contrib.auth.decorators import permission_required
from django.utils.decorators import method_decorator
class MyView(View):
#method_decorator(permission_required('app.permission',raise_exception=True)
def get(self, request):
#your GET view
Hope this helps.
You can tap into the messages framework and provide an error message. See my answer to an identical question.
You could use login_url parameter in this decorator to redirect to some other page, rather than login page. Or you can simply write your own decorator based on the code from django:
def permission_required(perm, login_url=None):
"""
Decorator for views that checks whether a user has a particular permission
enabled, redirecting to the log-in page if necessary.
"""
return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)
Simply change login_url to some redirect_to and it won't cause any confusion.
Use #permission_required_or_403('codename')
This will redirect the users to a 403 'permission denied' error page.