I need to start using model-level permissions in my existing Django-based web service. The permission types I'd like to add are django admin's default ("add", "change", "delete") and are already there (I can see them in the admin.)
I have already many users in the database, so manual permission assignment is out of the question.
How do I auto assign these permissions for every existing user and for future users for a subset of model in my app?
You can use groups to do so, using the get_or_create method, like the code below:
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(User)
add_permission = Permission.objects.get(content_type=content_type,codename='add_user')
change_permission = Permission.objects.get(content_type=content_type,codename='change_user')
delete_permission = Permission.objects.get(content_type=content_type,codename='delete_user')
group, created = Group.objects.get_or_create(name='your_group')
if created: #assign permission to all users in database
group.permissions.add(add_permission, change_permission, delete_permission)
for user in User.objects.all():
user.groups.add(group)
This way, if the group is not yet created, you create it, add all users in your database to it and add the permissions you want. Also, for every new user you want to add those permissions, you should add it to the group, so the following code should go on their creation:
groupGroup.objects.get(name='your_group')
user.groups.add(group)
For documentation, click here
Related
I am trying to have roles, groups, and permissions in my custom admin dashboard (not the django admin) so as to assign roles, groups, and permissions. The django admin page for permissions looks like the image below. I want to have exact same permissions in my template.
In other frameworks like laravel, they have it done beautifully with the Spatie package. Is there any similar package too in Django or I have to write every single logic myself. Or better still can I query the Django-admin permissions and groups and display them in my custom admin dashboard template.
Django permission and group models can be imported:
from django.contrib.auth.models import Permission, Group
they are normal models like any other so you can query them:
Permission.objects.all()
You can also create other permissions:
from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)
All you need to do is to create endpoints for listing, adding and any other requirements that you might need.
More on Django docs: Programmatically creating permissions
O.K. I have a headache with this problem. I have to different sites(non django) with login option and I would like to join in it into one new website based on django.
Each of these two user databases consist of table with columns:(username, password, e-mail).
The problem is, I just can not copy it to User table in Django as we all know django is very rigid about it, so I am trying to think a way, existing users would be able to login to site as nothing has changed.
Is there any django/pythonic way to do so?
I was thinking to create an app, which would take a foreign key to User model. Within User model I would create two users (database_1, database_2), so whenever a user from database 1 would login, e.g. JohnSmith, he would be connected as database_1 user, but so would JessicaSimpson if she would be in database 1. I am just thing to create Authentication and Authorization app as system app in some way... Is this a right way thinking? Would love to hear from professionals. Thanks
in models:
from django.db import models
from django.contrib.auth.models import User, Group
# Create your models here.
class New_users(models.Model):
new_user_id = models.ForeignKey(User, unique=False)
username = models.CharField(max_length=25)
password = models.CharField(max_length=25)
email = models.CharField(max_length=25)
in views:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def home(request):
if request.method == 'POST':
#if username and password from New_users are ok...
login()#User where id is the same blah blah....
I'm a professional, and I would add the old users to the new DB and put in random passwords. I would also make a table of old_users with their old hashed passwords.
I would flag these old users such that, when they visit the new app, they would be forced to enter their old pw (you'd need to know the hash method) and, if successful, then set the old pw to the new user, and log them in.
If that's too much trouble, you could write a script that sends all the old users an email (naturally, you have their email address) and a link to a change_password form. It's pretty easy to extend the django reset password functionality. And it's a good thing to have.
Could you just migrate the existing users into the new database by looping through the existing users and calling the create_user function? This would take care of the password hashing and everything, assuming that you can decrypt your current passwords back to plaintext.
I have a Django server (Using PostGis) and I want to disable everything related to authentication:
When entering the admin no authentication will be required
In the admin hide the Users/Groups
After searching online I tried the combination of this & this
It does get me the result I hoped for, until I try to add an object via the admin. Then I get an IntegrityError:
insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_c564eba6_fk_auth_user_id"
DETAIL: Key (user_id)=(1) is not present in table "auth_user".
I tried solving it using solutions like this and it didn't help.
I don't mind having a solution in a whole new approach as long as the end goal is acquired.
Thanks ahead,
As the Django project is running in dockers, and can be deployed when the users already exist or don't I ended up doing:
# Create superuser for admin use in case it doesn't exist
try:
User.objects.get_by_natural_key('admin')
except User.DoesNotExist:
User.objects.create_superuser('admin', 'admin#comapny.com', '123456')
Hope this helps someone one day. Full use:
from django.contrib import admin
from django.contrib.auth.models import User, Group
# We add this so no authentication is needed when entering the admin site
class AccessUser(object):
has_module_perms = has_perm = __getattr__ = lambda s,*a,**kw: True
admin.site.has_permission = lambda r: setattr(r, 'user', AccessUser()) or True
# We add this to remove the user/group admin in the admin site as there is no user authentication
admin.site.unregister(User)
admin.site.unregister(Group)
# Create superuser for admin use in case it doesn't exist
try:
User.objects.get_by_natural_key('admin')
except User.DoesNotExist:
User.objects.create_superuser('admin', 'admin#optibus.co', '123456')
I have setup my Django (1.8) admin to allow superusers to create new users interactively. My User model is customized using AbstractUser which means my admin file looks like this:
admin.py
from django.contrib import admin
from app.models import CPRUser
class UserAdmin(admin.ModelAdmin):
model = CPRUser
extra = 1
admin.site.register(CPRUser, UserAdmin)
and here is the model:
class CPRUser(AbstractUser):
student = models.PositiveIntegerField(verbose_name=_("student"),
default=0,
blank=True)
saved = models.IntegerField(default=0)
This appears to work OK, I can go through the admin and set the password, username and all the other custom fields of a new user. However, when I try and login with the newly created user, some part of the authentication process fails. I login from a page which is using the auth_views.login view and the boilerplate django login template.
On the other hand, if I create a new user using either manage.py createsuperuser or createuser() within the django shell, these users can login fine. This leads me to suspect it is to do with password storage or hashing - currently in the admin I can just type in a new user's password. Thing is, that is what I want to be able to do. How can I get this desired result - I want non-IT savy managers (whose details I won't have) to be able to easily create new users in the admin. I am aware of the risks of such a system.
The docs seem contradictory on setting this interactive user creation up in one section:
"The “Add user” admin page is different than standard admin pages in that it requires you to choose a username and password before allowing you to edit the rest of the user’s fields."
and then a couple of paragraphs later:
"User passwords are not displayed in the admin (nor stored in the database)"
Here is a screen shot of my admin:
How can I make Django accept the login attempts of users created interactively via the admin?
This is described in the documentation,
If your custom User model extends django.contrib.auth.models.AbstractUser, you can use Django’s existing django.contrib.auth.admin.UserAdmin class.
So, extending UserAdmin should do the trick.
I am creating a python django project and while in admin I want to make it function like this:
the user opens thecustomer window which would show a list of all customers then if the user has a certain permission a location filter is visible but if there is no permission then the filter is not visible.
Is this possible and if yes then how?
You can override the get_list_filter method of your ModelAdmin and check for permissions in there.
Example:
MyAdmin(admin.ModelAdmin):
def get_list_filter(self, request):
if request.user.has_perm('some_perm'):
return ['filter_1', 'filter_2', ......]
else:
return []