Which Django model should be used for staff members? - python

For a project (my own pet project) I am doing, I have an app called 'staff'. The ideas is 'staff' will contain list of all staff members in my organization. Now, they have to have an ability to login to the system and check what assets were assigned to them. The question is which built-in model (User, AbstractBaseUser, or AbstractUser) I should use for the 'staff' app? I've started with models.Model, however, I am thinking it might not be correct choice.

You can use the default User model that has a boolean field called is_staff. Then allow only user with is_staff==True to use the restricted system. You can change the value of is_staff in the admin interface. If you want a custom User model, subclass AbstractUser in the models of your staff app, then add this in your settings (if you want that your custom model is used for authentication): AUTH_USER_MODEL = 'AppName.CutomUserModelName'

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.

Django-Nonrel AbstractUser Permissions

I am working on a project and I have decided to use Google App Engine for hosting (Django-nonrel). The website will have multiple types of users (inheriting from AbstractUser), and I want to be able to create permissions to control what a user can see/do. Since the native Django permissions do not work on Nonrel, I tried using permission_backend_nonrel, however it only works if you use the standard User model.
I have spent lots of time searching for how others have gotten permissions to work on Nonrel and AbstractUser, but have not found anything. It seems like I should give up on getting permissions to work and just create fields within the user models to replicate permissions. For example, if I want only some users to have the ability to change their email address, then I could do:
accounts\models.py
class UserProfile(AbstractUser):
address = models.CharField(max_length=40)
can_change_email = models.BooleanField(default=True)
customers\models.py
class CustomerProfile(UserProfile):
company = models.BooleanField(max_length=40)
In this scenario I could set 'can_change_email' and control this behavior in the views for UserProfile.
I would prefer to use the built-in permission system, but running out of ideas. Any suggestions?
I'd say you might have better luck creating separate one-to-one models to signify the difference between your users. Django expects you to have a single user model.
Another option is to use the normal User model and create proxy models that reflect the changes you want to have between users.
The first way:
class CustomerProfile(models.Model):
user = models.OneToOneField(User)
The second way:
class CustomerProfile(User):
class Meta:
proxy = True

django-oauth2-provider with custom user model?

I am really stuck in my project right now. I am trying to implement Oauth2 for my app. I found out about django-oauth2-provider a lot and tried it. The only problem is, it uses the User model at django.contrib.auth. The main users of our site are saved in a custom model called User which does not inherit from or extend the model at django.contrib.auth.
Is there any way to use my custom User model for creating clients and token?
If django-oauth2-provider can't be used for this purpose, can anyone recommend me some oauth2 library with the option to implement oauth2 with my own model.
Sincerely,
Sushant Karki
As the previous answer suggested, you should extend AbstractUser from django.contrib.auth.models.
The problem with the access token that the OP referring to, occur when changing the setting AUTH_USER_MODEL AFTER django-oauth2-provider was migrated.
When django-oauth2-provider is migrated, it creates a key constrain between the User model and django-oauth2-provider.
The solution is very easy:
Create your new User model and change the AUTH_USER_MODEL setting.
Go to the django_migration table in your database.
Delete all rows of django-oauth2-provider.
run python manage.py makemigrations
run python manage.py migrate
Now, the django-oauth2-provider tables are connected to the RIGHT User model.
django-oauth2-provider fetches the user model using settings.AUTH_USER_MODEL, with a fallback to auth.User. If you extend AbstractUser your User model will include all the fields of auth.User plus any additional fields you specify.
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
some_additional_field = models.BooleanField(default=False)
Specify the user model to be used like this in settings.py:
AUTH_USER_MODEL = 'user_api.User'
If you don't want to base your user on AbstractUser you'll also need to write your own user manager, e.g. by extending the BaseUserManager
You can read more about ways to customize django's user model here.

In Django correct way of extending a model

What is the best way to extend third party model in django 1.5?
Suppose I have 3rd party model called Feedback:
class Feedback(models.Model):
user = models.ForeignKey(
'auth.User',
verbose_name=_('User'),
related_name='feedback_form_submissions',
blank=True, null=True,
)
email = models.EmailField(
verbose_name=_('Email'),
blank=True,
)
...
I have my own user class. I need to override the user field. email I need to make blank=False and presumably want to add another Field to the model. What is the best way to do this?
Depending on the circumstance, that is, which 3rd party app you are using, you can approach this in a variety of ways:
Explicity inheriting from a model:
class CustomFeedback(Feedback):
#etc
Create a custom app:
Extend the app by doing a django-admin.py startapp AppName_custom which is a technique I have used with some apps. In that case you will want to inheret from a class like above but intercept DB methods like save or clean.
Fork the app. This is easily the most difficult way of doing this if you are inexperienced with Django. Just clone or fork via git or mercurial then add whatever code you need to modify the behavior of the app.
As a rule of thumb (pardon the expression) you shoudln't modify the User model since the Auth module is nicely comparmentalized. Instead you should use an app like django-profiles to add data to models or extend Forms.
Have you looked at this post? How to make email field unique in model User from contrib.auth in Django
I think it answers everything you want.
Django also includes documentation on how to do this here: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-user
You can also designate a custom User model for Django to use with AUTH_USER_MODEL = 'myapp.MyUser'. From there you can set your custom fields.

What's the proper way to use multiple AUTH_USER_MODEL in Django 1.5?

I want to use two different models for django.contrib.auth module. The first one is the default User model provided by Django which is completely suitable for admin access (groups, permissions etc.) but the other one is customer model which has a lot of different attributes (city, locale, address etc.) compared to default User model. These user groups must use different tables and mustn't have any relation.
I created a Customer model inherited from AbstractBaseUser and a middleware class called ChangeBaseUser like this:
class ChangeBaseUser(object):
def process_request(self, request):
match = resolve(request.path)
if match.app_name == "myapp":
settings.AUTH_USER_MODEL = 'myapp.Customer'
else:
settings.AUTH_USER_MODEL = 'auth.User'
It's working but I'm not sure whether this is the proper way to do it because in documentation there is a section (link) that implies the convenient way is to assign a static value for default user model.
If this is not the proper way, do you have any suggestions for having multiple user models per module basis?
If your requirement is to keep admin users and customers separate, I don't see anything wrong with having multiple user models. At this point, the customer model is like any model, except it is very similar to the user model and that is perfectly fine if that works for you. The only disadvantage is that you will have to possibly duplicate many helpers django gives you for the Django user model such as auth backend or sessions for users. If you are willing to do all that, this seems perfectly fine.
If you wish however to utilize many of the django helpers you might want to create a very basic user model which will serve as a base for both admins and customers:
class User(AbstractBaseUser):
# use this for auth and sessions
class Admin(models.Model):
user = models.OneToOneField(UserBase, related_name='admins')
# ... other admin-specific fields
class Customer(models.Model):
user = models.OneToOneField(UserBase, related_name='admins')
# ... other customer-specific fields
This will allow you to reuse many of the things Django provides out of the box however it will incur some additional db overhead since more joins will have to be calculated. But then you can cache things for customers so you can get some of the performance back.

Categories