Django .is_superuser field permission - python

By default from project directory by running manage.py createsuperuser command I am able to create a superuser, but the .is_superuser flag is the default django flag to differ superuser or other user.
I don't want to use that because i am using that flag throughout the application to show settings menu. Instead, I added a field in my userprofile models, the field is .is_primary_user.
Is there any way to control that, so that if I run createsuperuser comment, it should update the .is_primary_user field by "1" in userprofile model?

Yes there is, you have to catch the signal of the post_save of the User model, and if the .is_superuser is changed, you also change the .is_primary_user.
Has Brian Neal pointed out, you should not use the .is_superuser flag in your application. It is meant to be used along with Django permission system (a superuser has permissions for everything) and/or Django admin.
EDIT: I haven't tested, but it should be something like this:
from django.db.models.signals import pre_save
from django.contrib.auth import User
# method for updating
def update_primary_user(sender, instance, **kwargs):
if instance.pk:
return
if instance.is_superuser and not instance.userprofile.is_primary_user:
instance.userprofile.is_primary_user = True
instance.userprofile.save()
# register the signal
pre_save.connect(update_primary_user, sender=User)

There are two options as I see it. One is on the post save signals for profile and user. The other is to override the profile save method. The later will only handle new users.
The post save signal for either the user model or the profile model can be used for updating the profile models is_primary_user. Then not only when you run the createsuperuser program can you update the profile accordingly, but if you give an existing user superuser rights, it will also update that users profile. The problem with using the user model signal is that the profile may not yet be created. You probably would need to catch signals for both models. One for if a user is updated (user model), and the other (profile model) for if the user is being created.
Another option is to override the profile save method. You could check the user.is_superuser that it is linked to and then update the is_primary_user field accordingly.
On the other hand, you maybe wanting to do this for only the first superuser which is created in which case you would first need to check if any superusers previously existed.
I agree with two other posters that it would be best not to use the is_superuser flag in this manner.

Related

Why do we have to include staff and admin fields in custom user django model?

Let's say I am building a social networking website that has nothing do with admin and superuser. But I still have to include these fields while making custom user model. This is going to be a simple model that has user's profile information not that user is admin or superuser.
Can anyone explain why do we always need these fields to be there. Can we get rid of them and still create a Custom user model or do we always need them.
There is no constraint mentioned in the Django documentation that the AUTH_USER_MODEL specified should have is_superuser or is_staff flags. The minimum requirements for creating a custom user model is specified here
It is upto your business requirement to decide whether or not to follow them. But if your auth model does not have those flags, then it will not be possible for even you (the admin) to access the admin portal. So there is no harm in having the flag turned off for everyone.

updating field in user model whenever it used

I have extended user model in my project and need to update its field (last online) whenever user has authenticated. I use DRF and IsAuthenticated in permission classes, what is the best way to trigger update event?

unregister or register models conditionally in django admin

Is it possible to conditionally register or unregister models in django admin?
I want some models to appear in django admin, only if request satisfies some conditions. In my specific case I only need to check if the logged in user belongs to a particular group, and not show the model if the user (even if superuser) is not in the group. I can not use permissions here because, superusers can not be ruled out using permissions.
Or, is there a way to revoke permission from even superusers on model.
Permissions on a model can be managed dynamically in ModelAdmin.
Override the methods has_add_permission, has_change_permission and has_delete_permission.
class MyModelAdmin(admin.ModelAdmin):
def has_add_permission(self,request):
# if request satisfies conditions:
# return True
#else:
# return False
Same goes for other two methods. This works for superusers also.
If you revoke all three permissions MyModel will not be listed on admin site.
If you only require to hide model entry from admin site, simply override
get_model_perms method. You don't have to override permission methods.
def get_model_perms(self, request):
return {}
However, this method does not revoke permissions from the model. Even if the model is not listed on admin site, it can be accessed by entering url.
I've tried a couple of approaches locally, including overriding an AdminSite, but given the fact that all admin-related code is loaded when the app is initialized, the simplest approach would be to rely on permissions (and not give everyone superuser access).

Mezzanine customizing Profiles

I have a project where I need to extend django's User. The way I did this initially (without Mezzanine) was to subclass Model into a custom Profile which had a one-to-one Field to django's User. Aditionally, to guarantee that each user always has a Profile, I created in my app a receiver that would listen to the user_registered signal. Whenever it was triggered I would just do inside the receiver:
user = kwargs.get('user')
profile = Profile(user=user)
profile.save()
Now with Mezzanine a settings exist called AUTH_PROFILE_MODULE which I just set equal to 'myapp.Profile' and Mezzanine does the Profile creation for me. There are two issues though:
a) On my webapp, every time I access my profile page, I'm getting this:
myapp/venv/local/lib/python2.7/site-packages/mezzanine/accounts/templatetags/accounts_tags.py:70: DeprecationWarning: The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated.
profile = user.get_profile()
Indeed, AUTH_PROFILE_MODULE used to exist in django but was deprecated. What should I do? Do I ignore the warning since it's Mezzanine, not django, who's using AUTH_PROFILE_MODULE? Or does Mezzanine have a different way to handle profiles now?
b) On my receiver which I had without Mezzanine, I did more things. For example, I initiated Profile vars depending on some environment vars. How can I still do those custom things with Mezzanine? My old receiver isn't working anymore.
Thanks for any help
This question is a bit old, but I think you can safely ignore the warning.
You should be able to accomplish the extra configuration by connecting to the pre or post save signal for the profile model.

Is there a way to send a user email when user object is created?

In the system I am building user CAN NOT register them selves. The users are added by one of the system admins. So there is no user registration form or view. The registration is only being done in the admin so I guess that the send_mail has to be over there also (or am I wrong)?
I need to send an automatic email to the user when he/she is being created and only then (not on every save of the model).
Can any one help with this? Is there a built-in something for that? or how do I do that?
I've read about the create_user user Manager, but I thought there is a better way then editing a manager.
You can register a callback on the post_save signal for the User model. Somewhere along the lines of:
# note: untested code
from django.db.models.signals import post_save
from django.contrib.auth.models import User
def email_new_user(sender, **kwargs):
if kwargs["created"]: # only for new users
new_user = kwargs.["instance"]
# send email to new_user.email ..
post_save.connect(email_new_user, sender=User)
Note the if kwargs["created"]: condition which checks if this is a newly created User instance.
Use the post_save signal, which has a created argument sent with the signal. If created is true, send your email.
Edit
Shawn Chin beat me to it. Accept his answer
You can use the signals framework. A post-save signal on User objects will be appropriate, see here for a similar example.

Categories