I have an apps and I am making used of django admin, but my apps does not allow deleting of data and django admin have a delete button/link. I have already removed the delete action.
my question is, how can i remove the delete button/link in admin page in django?
class MyAdmin(ModelAdmin):
def get_actions(self, request):
actions = super(MyAdmin, self).get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
def has_delete_permission(self, request, obj=None):
return False
If the delete permission is not given the "Delete" button of a single object will disappear. The changelist "action" (select list to apply to objects with checkbox checked) will still be shown because you may have the permission to delete some of the objects. You can remove both with the above code.
CLARIFICATION (for the downvoters): admin checks if the current user has the permission to delete and then shows/hides the button/s accordingly. You wrote "my apps does not allow deleting" so I assumed you took away permissions. A superuser does not get looked up in permissions, superuser always returns "yes I have that permission". If you want the buttons to disappear for superusers, you have to use my above code. For other users just take away the permission as per Secator's answer.
Do not remove or change anything in the admin.
Instead remove user's/group's permission to delete given model. If user does not have the permission to delete, the delete button won't appear at any page related to that model.
Related
I have a complete Login and Registration system in my Django app, that lets me register users, log in users, logout users, change passwords, reset passwords, invite users. I have all the basic functionality.
I want now to have Workspaces for users, as per following points:
There will be a workspace admin of each workspace.
Workspace admins can only add/remove (register/delete) users to his own workspaces.
Users can react to (log in to) only those workspaces to which they have been added.
A superuser (main admin) can manage all workspaces, all workspaces-admins and all users.
How do I accomplish this? You can say this is similar to a Slack thing. I just need a guidelines/roadmap and I will implement it myself.
I have already created a Workspace Model, which looks like below:
class Workspace(models.Model):
name = models.CharField(max_length=254)
created_at = models.DateTimeField(auto_now_add=True)
def make_admin(self, user):
user.is_workspace_admin = True
user.save()
def remove_admin(self, user):
user.is_workspace_admin = False
user.save()
and my User model has following two attributes beside other default Django fields:
class User(AbstractBaseUser, PermissionsMixin):
is_workspace_admin = models.BooleanField(default=True)
workspaces = models.ManyToManyField(Workspace)
Is this approach correct? If not please guide me to the proper way. BTW, using this approach, I can add/assign workspaces to any user, but how will I be able to manage the users logging in their own workspaces and reacting with only their workspaces to which they have been assigned. And also workspaces admins controlling their workspaces’ users etc?
I know about using Groups. So let's say I create all relevant permissions (Can you also tell me how to create permissions?) to add workspace user, remove workspace user, make workspace user a workspace admin, remove workspace admin from workspace adminship etc. and create different Groups and add relevant permissions in each group. Suppose my groups looks like manage_workspace_a to manage (add/remove) the workspace users groups, manage_workspace_admins to manage (add/remove) workspace admins, and default permissions that Django provides for each Model.
So, how will i be able to have the functionality that when a "User A" that has is_superuser=True, makes the is_workspace_admin=True of "User B", then "User B" should automatically gets all the Workspace Admin Permissions. Something like this:
workspace_user = User.objects.get(email="some-email-address")
if request.user.is_superuser:
wordspace_user.permissions.add([Workspace Admin Permissions])
Can somebody explain the whole process with a small code example?
This is a very long, multi-part question but hopefully I can point you in the right direction
I would suggest adding another Many-to-Many field on your User model that handles administrator status. At the moment, you have it set to Boolean flag - so an administrator can either manage all workspaces or none.
Personally, I would reverse the M2M status and put users and administrators on the workspace, rather than on the user model. It's not problematic to have on the user model but I feel it makes more sense to check that the user is in the workspace's permitted users/admins rather than the workspace is in the user's list of workspaces and admin workspaces.
You will need to change your code that adds an administrator to a workspace as you won't want to use a boolean flag:
def make_admin(self, user):
self.administrators.add(user)
As to how you manage the workspace itself, you can just put ORM filters at the very start of your relevant views:
def workspace_view(request, workspace_id):
workspace = get_object_or_404(Workspace, workspace_id)
if request.user not in workspace.users:
return redirect(...)
...the rest of your view
Bear in mind that this doesn't allow administrators in unless they are in the users group - you will either need to add them to users or add another condition to check if they are in administrators.
If you want an overview of all the workspaces in some sort of index/home page, you would just use the m2m reverse accessor which depends on your reverse name (or /relation/_set by default):
def workspaces(request):
workspaces = request.user.workspaces.all()
You can definitely leverage Django's in-built permissions system, I would point you to the documentation because that is a long subject:
https://docs.djangoproject.com/en/4.0/topics/auth/default/#permissions-and-authorization
So I have this method:
def create_editor(self, email, dob, password):
user = self.create_user(
email,
dob,
accepted_tos=True,
password=password
)
try:
editors = Group.objects.get(name__iexact="Editors")
except Group.DoesNotExist:
editors = Group.objects.create(name="Editors")
editors.permissions.add(Permission.objects.get(codename="can_give_discount")) # add can_give_discount permission
user.groups.add(editors)
user.save()
return user
To create a normal user and then add the user to the editor group
I want to be able to create a manager from the normal django admin.
So in the image below I want another button called Add Manager
At first it looks like what you want to do is create a new Manager model that has a foreignkey to user. Then from the admin side you have the option to first click add user, then navigate to the Manager model and add a manager (where you also supply the user id so they are linked by foreignkey).
However if this is only done to accommodate permissions and groups you can also go to the groups model in django admin.
Spoiler alert, the django admin is not really made for customizations. But there are some think which django is prepared for, checkout the django admin docs here https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#custom-template-options.
It might be a solution for you to extend/override your existing create user template (see here: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#overriding-vs-replacing-an-admin-template) to e.g. add ad flag that makes the new user an editor or not and you could override the User.objects.create() method to use the flag.
The solution with the least amount of work but 2 steps would be to add an admin action (if you want the button in the detail view: django object action https://github.com/crccheck/django-object-actions) to "upgrade" a normal user to an editor.
Or maybe you could add another choice field extending the User to say whether the added guy is 'Editor' or 'Manager' and on save check if the added user is 'Manager' or 'Editor', and override save to add the new user to the corresponding group.
I am making an app. In which multiple superusers are there and beneath these super user we have multiple user. I am able to make superuser.But I am not able to add user in that for that super user.I am relatively new in django.
Superusers are special as their permission system returns True on every permission request (it is hardcoded). There is no "super group". You can simply create a group and give it all permissions (so add, change and delete permission to every model).
I've installed django-userena to manage user profiles and everything works fine except new registered users unable to edit/update their profiles and face just blank screen.
If I make the user a superuser then it can change/update profile.
Found that profile_edit view in django-userena decorated with #permission_required_or_403('change_profile', (get_profile_model(), 'user__username', 'username'))
Obviously need to add post_save signal to add necessary permission and nevertheless I was wondering if there any settings like USERENA_ALLOW_UPDATE_PROFILE can anyone help me on this?
Finally digging around django-userena and django-guardian sources I present my output of this little research, so if you want the users to be able to edit their profile you can use the following code
User post save signal which adds 'change_profile' permission to new user objects
#receiver(post_save, sender=User, dispatch_uid='user.created')
def user_created(sender, instance, created, raw, using, **kwargs):
""" Adds 'change_profile' permission to created user objects """
if created:
from guardian.shortcuts import assign
assign('change_profile', instance, instance.get_profile())
For existing users, Just issue this command and the page will be working:
python manage.py check_permissions
I'm searching for a way to customize the Django Administration to support permissions based on the user group.
For example, I've just created the Developers group, now I've also created the Tickets model, with AdminModel to specify how to list data.
I'd like to have this model visible only by Developers, and hidden to each other not in this group (eg filter the view based on groups).
I've read a lot of documentations, but couldn't really find and understand what to do to have it working.
For security purposes I'd also need to check user groups at runtime when adding-deleting objects for a specific model (the one I've hidden to people outside the Developers group), otherwise it would only need to know the URL to use the model :s
It looks like a simple task, but maybe I'm missing something... any 3rd party middleware, or just a way to do it? I'm also ready to edit the administration views if needed, but I need to know what do to.
Thank you :-)
ModelAdmin has three methods dealing with user permission: has_add_permission, has_change_permission and has_delete_permission. All three should return boolean (True/False).
So you could do something like:
class TicketAdmin(admin.ModelAdmin):
...
def has_add_permission(self, request):
return request.user.groups.filter(name='Developers').exists()
def has_change_permission(self, request, obj=None):
return request.user.groups.filter(name='Developers').exists()
def has_delete_permission(self, request, obj=None):
return request.user.groups.filter(name='Developers').exists()
When False is returned from one of these, it's results in a 403 Forbidden.
I had tried hours to find a way to edit custom admin's(based on my custom model) permission by some click on screen,without many coding.
Use Django's /admin/auth/user/ "User permissions:part"
Finally I find this:
Just to install django-admin-view-permission
and I can change the staff's custom models' permission here
Also in the group part /admin/auth/group/add/ I can create a group has certain permission, and assign specific staff to their permission group.