Django user delete privilege role - django

Is possible to give roles/group to admin users to delete only the users they created?
For example:
admin1 created user1, user2
admin2 created user3, user4
admin1 should only have permissions to delete user1 and user2 and not have any access to user3 and user4.

in user model you can add the file creator ForeignKey to admin:
class User(AbstractUser):
creator = models.ForeignKey(User, on_delete=models.CASCADE)
......
when admin delete user check the creator:
def userDelete(request, userId):
user = get_object_or_404(User, id=userId)
if user.creator == request.user: // have access
article.delete()
messages.success(request, 'User Delete')
return redirect('***:***')

Since changing the user model mid-project may result in complications, another approach to extend the existing User model can be:
from django.db import models
from django.contrib.auth.models import User
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='custom_user')
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
And now you can use the created_by field as mentioned by #ming in their answer.

Related

Why does Django not find a field added to the AbstractBaseUser

I've inherited from the AbstractBaseUser as follows:
class User(AbstractBaseUser):
"""
Main User model, inherits from AbstractBaseUser
"""
# Meta
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.CharField(max_length=40, unique=True) # equals to email
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True)
So each User is linked to one and only one Customer.
Now within a view I want to access the instance of the current logged in user within the request object and get the employee_of value to get a queryset that contains all users of that customer.
def render_employees(request):
"""
Renders the employees page of the dashboard
:param request:
:return:
"""
# Return the value for the current site for css specific classes
dashboard_site = 'employees'
# Query the employees
qs_employees = User.objects.filter(employee_of=request.user.employee_of) # doesn't find field
...
However the filter doesn't work because request.user.employ_of doesn't seem to return anything. My IDE even suggests e.g. username, date_joined etc. but not employee_of.
Why's that?
class Customer(models.Model):
"""
A table that stores static data about a customer, usually a legal company
"""
legal_name = models.CharField(max_length=50)
street = models.CharField(max_length=30)
street_number = models.CharField(max_length=3)
def __str__(self):
return self.legal_name
Update:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from applications.customer.models import Customer
from django.conf import settings
BaseUser = settings.AUTH_USER_MODEL
class User(AbstractBaseUser):
"""
Main User model, inherits from AbstractBaseUser
"""
# Relations
user = models.OneToOneField(BaseUser, related_name='user_profile', on_delete=models.CASCADE, null=True) # link to default user model
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True, blank=True)
I linked the user to the default user model via Django admin. However in the view im still not able to access employee_of within request.user
It seems that request.user is a different model. It's User model from django.contrib.auth. https://docs.djangoproject.com/en/4.0/ref/contrib/auth/#django.contrib.auth.models.User.
What you can do about it?
In our app we have UserProfile model that have OnetoOne relation to django User.
You can then store employee_of value there.
class UserProfile(AbstractBaseUser):
user = models.OnetoOneField("auth.User", related_name="user_profile", on_delete=models.CASCADE)
employee_of = models.OneToOneField(Customer, on_delete=models.SET_NULL, null=True)
and then access request.user employees using something like
request.user.user_profile.employee_of

Django how to link Users to Usermodel

Hello I am pretty new to Django and don't get yet fundamental ideas of Users.
I was able to create a registration page to create users which are shown on the admin page in the "Authentication and AUthorization -> Users".
Now I want the users to logg in and create their profiles. They should add some additional information like name, bio, picture etc.
Every user should be able to add and see its own profile.
To do that I created a model:
class Profile(models.Model):
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
bio = models.TextField()
profile_pic = models.ImageField(upload_to="images/")
def __str__(self):
return self.firstname + ' | ' + self.lastname
In my view and the html I am able to add these informations to the model.
But HOW exactly can I relate this "Profile"-Model to the individual user? What do I miss here?
You can do this via adding a OneToOneField relationship between Profile and the default User:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
bio = models.TextField()
profile_pic = models.ImageField(upload_to="images/")
def __str__(self):
return self.firstname + ' | ' + self.lastname
You can make a OneToOneField to the AUTH_USER_MODEL setting [Django-doc]. This settings contains a string with the qualified name of the user model. This is better than linking to the User model of django.contrib.auth.models.User, because if you later create a custom user model, the references to that user model will be updated:
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
# …
For more information, see the referencing the user model section of the Django documentation.

Django models: Parent model accessing child model field

I have the following models
from django.contrib.auth.models import User
User = settings.AUTH_USER_MODEL
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
class Tutor(UserProfile):
# tutor_fields here
From User object how can I access Tutor? is it with user.profile?
user.profile.select_related('tutor') does not seem to work.
OneToOneField work like ForeignKey except unique=True and you don't need to specify the related_name (you can specify if you want to change it).
For you example:
from django.contrib.auth.models import User
User = settings.AUTH_USER_MODEL
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
class Tutor(UserProfile):
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name='tutor')
details = models.CharField(max_length=100)
NB: Use a ForeignKey if you want/need one Tutor for many UserProfile, else if you want one (and only one) Tutor for one UserProfile
And you can access to the Tutor bu UserProfile by UserProfile.tutor.details.
As described in the django docs, you should be able to access it with user.user_profile.

How to extend Django auth model User with UserProfile, avoiding RelatedObjectDoesNotExist error?

I am trying to create UserProfile modal by extending default django User. Additional value cannot be saved because User has no user profile:RelatedObjectDoesNotExist:
user = User.objects.create_user(username=username, password=password)
user.save()
print(fb_id)
user.userprofile.fb_id = fb_id
user.userprofile.save()
modal :
class UserProfile(models.Model):
user = models.OneToOneField(User)
fb_id = models.BigIntegerField(null=True, blank=True, default=0)
follows = models.ManyToManyField('self', related_name='followed_by', symmetrical=False)
Can't understand why it's wrong and how to do in the right way? Django 1.8
You can't access user.user_profile until you have created it. You could do:
user = User.objects.create_user(username=username, password=password)
userprofile = UserProfile.objects.create(user=user, fb_id=fb_id)

Django: User Profile in 1.9

RELATED: get user profile in django
The above shows how to get user profile but i read that the accepted answer method is deprecated.
How would I create/get/use user profile in django 1.9?
models.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
address = models.TextField()
......
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
The above code will create a UserProfile record whenever a new user is created on User table. Then you can access the profile details like,
address = request.user.profile.address
get_profile() method returned additional informations about User. Currently, these informations can be stored in Custom User Model or in a seperate model which is related to User Model. You can do that by simply adding one2one relation with User model to your custom User model, or by subclassing the AbstructUserBase model.
Subclassing User Model example:
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
date_of_birth = models.DateField()
...
One2One Relation with User model example:
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)