Unsure of approach for Django custom user groups and permissions - django

I am creating my first Django (ver 3.1) website which is simply a blog with a home page and store page. I want to create custom user groups that define specific roles (with unique permissions) for my blog.
These groups are:
Reader - anonymous viewers and new accounts; has read permission for all content only
Author - login required; has read and create permissions; edit and delete permissions for own content only
Moderator - login required; has all CRUD permissions for all content
Admin - login required, has all permissions (superuser)
All new users by default are in the Reader group. Author would either be assigned manually or eventually by an online form application to determine eligibility. Moderator and Admin would of course be manually assigned.
I am approaching this with possible future development, such as allowing user groups to be easily extended to other website pages. For example, a 5% discount for Author users applied to all store items, etc.
Which approach to creating user groups would be best for my situation? I have seen it done within the Django Admin Panel and by creating custom User Models via extending the AbstractBaseUser and UserBaseManager classes.

I think extending the AbstractUser model is a good approach. How about something like this?
class CustomUser(AbstractUser):
"Define the extra fields related to User here"""
first_name = models.CharField(_('First Name of User'), blank=True, max_length=20)
last_name = models.CharField(_('Last Name of User'), blank=True, max_length=20)
#  - - - Some more User fields according to your need s
class Meta:
permissions = (("can_read_content", "To provide read facility on all content"),
#---------------------
)

Related

Can I implement separate user authentication and models for two apps in django project?

In this django project I have two separate applications that I need to keep user account information separate. For example, if a person creates an account for app A, I need them to be able to make a separate account (with the possibility of using the same unique email for account creation) for app B. At this moment in time, it seems as though there is no way for me to handle having two separate auth models for two separate users. I am wondering what the django workaround for this might be, or if I am misunderstanding the problem in some way?
Here is an example user model that would work for both application A and B, but would need separate tables or models for authentication and account creation:
class GenericUser(AbstractUser):
"""abstract user class for user authentication"""
firstname = models.CharField('First Name', blank=True, max_length=100)
lastname = models.CharField('Last Name', blank=True, max_length=100)
email = models.CharField('Email', unique=True, max_length=100)
class Meta:
permissions = (
("some-permission", "some-description"),
)
First I tried creating two separate user entities in the models.py file in my django project, however when I finished doing this, there was nowhere to put the second user model in the settings.py folder. This is where I am stuck now.
May be you are looking for this .. django support multiple authentication model. in order to do this you need to create a custom authentication backend by inherit from 'django.contrib.auth.backends.BaseBackend' (you can specify different user model there, I think ) and specify the authentication model in the settings.py of the project.
For more information. check this doc

Rename django custom permissions

I'm working with django 2.0 app and going to update django version to 3.0.
But in my project there are few custom permissions named like view_modelname.
class MyConcreteModel(models.Model):
model_field_1 = models.CharField(max_length=100, blank=False)
# other fields
class Meta:
permissions = (
("view_myconcretemodel", "Can see available device interfaces"),
)
In django 3 (since v 2.1) such kind of permissions are default. So I got conflict with permission names.
Now I'm trying to rename custom permissions before updating django version.
class MyConcreteModel(models.Model):
model_field_1 = models.CharField(max_length=100, blank=False)
# other fields
class Meta:
permissions = (
("user_view_myconcretemodel", "User can see available device interfaces"),
)
After migration 'new' (with new names) permissions were created in DB. But old permissions still there and all users have old permissions (with old names like view_myconcretemodel). Obviously I need 'new' permissions for all users.
Is there possibility simple to rename permissions or give 'new' permissions to relevant users (according to 'old' permissions), and do it automatically?
After reading how to Programmatically creating permissions https://docs.djangoproject.com/en/3.2/topics/auth/default/#programmatically-creating-permissions
My solution is to modify codename in Permission model. i.e.
from django.contrib.auth.models import Permission
perm = Permission.objects.get(codename="view_myconcretemodel") #old name
perm.codename = "user_view_myconcretemodel" #new name
perm.save()

Permissions from 2 django projects are merged. How to separate them?

Good day to all)
I created a custom user model with custom permissions. I have several projects and their permissions merged into one table('auth_permission'). Is it possible to somehow customize the table itself for these permissions to separate projects?(like db_table = '"schema"."table"' to the models.).Google did not give answers.
class TestUser(AbstractUser):
phone = PhoneNumberField(null=False, blank=False, unique=True)
email = CharField(unique=True, max_length=35, null=False, blank=False)
class Meta:
db_table = '"fyzzys"."users"'
permissions = [
("can_see_payments", "payments"),
("can_see_analytics", "analytics"),
]
UPD: Here is a screenshot that shows the permissions of two completely different projects at the same time from admin panel.
In order to give a user permissions, you will want to add the PermissionsMixin to the User model like so.
class TestUser(AbstractBaseUser, PermissionsMixin):
If you are using the AbstractUser you are actually already inheriting the PermissionsMixin.
The permissionmixin is a model within django.contrib.auth.models. It adds to the user model the following fields (columns in the user table); is_superuser, groups, user_permissions. The permissions mixin allows you to add (and remove) 0..*(many) individual or group permissions to a user.
To add permissions to a user you can then use.
from django.contrib.auth.models import Permission
# The permission needs to exist first.
permission = Permission.objects.get(name='Can view poll')
u.user_permissions.add(permission)
The code for for the django.contrib.auth.models.permissionsmixin can be found following the link.

Django Database structure, How to handle slug from two different models like Facebook does?

I have a project that publishes job offers, a job seeker can create a profile on the website and his profile page will have URL like:
www.domain_name.com/slug
An institution publishing job offers can also create an account.The person actually creates the institution account will be considered as the administrator of the institution page, so he will have an account (*instance of UserProfile() and can add other members (Users on the platform not affected to any institutions) to that institution. Institution profile URL will be www.domain_name.com/institution_slug
Members will have their own UserProfile instance linked to that institution, and once connected, only the institution page data/functionalities will be visible, they will work as the institution.
So What is the best way to have these 2 models and handle the URL pattern properly? like
urls.py
path("<slug:slug>",profile,name='profile')
views.py
def profile(request,slug):
user = UserProfile.objects.get(slug=slug) #get_object_or_404
inst = Institution.objects.get(slug=slug) #get_object_or_404
In above example, I don’t want to have to query twice in two different models. Is there another way to do it? Or If I need to re-design the database structure, let me know!
models.py
UserProfile(models):
# info_about_user
sug = models.SlugField()
institution = models.ForeignKey(Institution)
Institution(models.Model):
# info_about_instituion
slug = models.SlugField()
Note that both may publish job offers:
Job(models.Model)
owner = UserProfile or Institution

Django: Adding Permission to an Specific Model Instance

I am looking for the best way to implement user permissions to allow users to edit specific model instances.
For instance, I have such two models:
model RadioChannel(models.Model):
name = models.CharField(max_length=150, unique= True)
number = models.IntegerField( unique= True)
model ProgramSchedule(models.Model):
channel = models.ForeignKey("RadioChannel")
name = models.CharField(max_length=150, unique= True)
start_time = models.DateTimeField()
Now my Operators are my build-in Django users. I want to make groups for these users so that they can only add/remove/edit ProgramSchedules that are allowed. In addition I want to add groups to these users to the admin panel.
Thanks.
You are looking for an object permission implementation. A good comparison is here:
http://djangopackages.com/grids/g/perms/
Shameless plug:
Heres my fork of a very popular per-object permission app: http://github.com/azizmb/django-authority
If I am getting you correct, what you need to implement is called row level permissions in Django. Have a look at this if it helps. http://code.djangoproject.com/wiki/RowLevelPermissionsDeveloper
I would recommend using Django Guardian for object-level permissions.