How to handle users and roles by app in Django - django

Hello everyone let me ask something about the admin interface and how can I handle my users by app.
Well so sorry I'm nooby first of all. So, I need to create a new app for basically take some quiz so I will need users and these users within my app should have a different role as a student or teacher and so on.
The thing is that I don't know if the admin Django interface is just for the DB models or whether I can use it as a security layer in my app.
Or otherwise, I should create a buck of tables in my app model for users and roles and then handle everything from the model because the admin is just the DB access. what could you tell me? thanks so much.

From Django's documentation about Django admin - Link
model-centric interface where trusted users can manage content on your site.
Django comes with a user model, you can extend it to represent teachers and students as described in django's documentation here, you would create ModelAdmins and register your models. Beyond that you can manage your users easily through the admin system, example code:
models.py
from django.contrib.auth.models import User
from django.db import models
class Teacher(models.Model):
user = models.ForeignKey(User, related_name='teacher')
class Student(models.Model):
user = models.ForeignKey(User, related_name='student')
admin.py
from django.contrib import admin
from .models import Teacher, Student
admin.site.register(Teacher)
admin.site.register(Student)
As for security, it is not clear what you mean by "use it as a security layer in my app", if you elaborate more, people can better help you. You can generally learn about security in django here.

Related

django user custom model authentication and authorization

I have created a custom user model before making any migration and I wanted to move it from the app panel to the auth panel in the admin page.
To do that I created a proxy user model:
class User(AbstractUser):
pass
class ProxyUser(User):
pass
class Meta:
app_label = 'auth'
proxy = True
and then in admin.py:
from django.contrib.auth.admin import UserAdmin
from .models import ProxyUser
admin.site.register(ProxyUser, UserAdmin)
The problem is that the auth_permission table has permissions for user and proxyuser.
Can't understand why if I'm using a proxy and only one user table was created the permissions table behaves as if there were two (proxyuser and user).
Am I missing something?
Thanks in advance
Django uses the content type framework to keep track of "permissions" for various models. Proxy models get their own permissions.
This is explained in the authentication section of Django docs:
Proxy models work exactly the same way as concrete models. Permissions are created using the own content type of the proxy model. Proxy models don’t inherit the permissions of the concrete model they subclass
I feel what you're trying to achieve with the proxy model is unnecessary. I personally wouldn't worry much about 'Users' appearing under a separate section in the Django Admin. You will instead add unnecessary complexity to the code by using a proxy model (A future developer/you would wonder wether to use the custom User class or the ProxyUser class).
You may have done all migrations and no only for your apps, if you don't specify the app to migrate, Django makes all of the migrations. On the other way, maybe you can't log into the admin site if you doesn't do it.

How to create Multi User Account

Please am really need you guys help on how to use Django to create Multi-user Account.
e.g Student, Lecturers, and Department login page(Admin).
in this system, the department will be the Admin to register the lecturers in order to have access and why the Student register on their own.
Am design a project titled Online Assignment Submission System
(it is my final year Project). I really need you guys help on how to go about it using Django.
There are multiple options to deal with the user model in Django:
You could subclass AbstractUser or AbstractBaseUser and add a choice field if the user is a student, teacher, etc.
Linking back from a related 'Profile' model. This comes in handy if you want different types of users to have different fields.
models.py:
from django.conf import settings
from django.db import models
class StudentProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
subjects = models.ManyToManyField(Subject)
has_returned_books = models.BooleanField(default=False)
class TeacherProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
salary = models.IntegerField()
hours_per_week = models.IntegerField()
# ... other profiles for department, etc.
Using this approach, you can query fields with the ORM:
user.teacherprofile.salary or user.studentprofile.subjects.
When you have implemented your models you should read about the permission system in Django. You can limit access to logged-in users with help of a decorator or mixin.
Do some more research and come back asking specific question with examples of your recent work. The more work you put into the question, the more people will help you. Good luck!

How do i implement both built-in django auth and third party social-auth in my application?

I using django from last 4-5 months and recently started learning django-rest-framework and I'm confused about proper authentication system,
Actually I am trying to build an application mostly using REST API because my
client can be both browser and Android,
so I need an authentication system in which user can sign up using both django
built-in auth(django.contrib.auth.model.User) as well as third-party social
authentication(Google, Facebook, etc..).
Now, I'm confused about how do I create my database, because when ever i'll create
a table/model lets say a 'Book', then this model would need a foreign key to the user model and here user can be both 'django.contrib.auth.model.User' and a user signed-up using third party auth,
So how I will refer to User in foreign key Field of my models?
And I have also decided to customize django's buit-in auth because i want
user to login using their email not username.
class Book(models.Model):
title = models.CharField(...)
author = models.ForeignKey(?) ? Here, how do i refer to both
'django.contrib...User' and users signed-up
using thrid-party auth.
Let me elaborate on your question.
First of all: You're lucky. There's an (almost) out of the box version for your problem.
For social and normal authentication and registration, including email verification etc. you can rely on django-allauth:
https://github.com/pennersr/django-allauth
django-restauth provides a restful platform built on top of all-auth, so that you don't even have to start building your auth rest api from scratch:
https://github.com/Tivix/django-rest-auth
When it comes to your db schema, there are a few options. You could go ahead and build your own authentication system, which, in my opinion, is overkill.
Rather more, I would implement a profile model, which has a OneToOne relationship to the User model from django.contrib.auth.models.User as described in this chapter of the Django docs.
Your models (of course in separated apps) would look like this:
from django.contrib.auth.models import User
from django.db import models
#other imports
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
books_read = models.IntegerField(default=0)
books_recommended = models.IntegerField(default=0)
class Book(models.Model):
title = models.CharField(...)
author = models.ForeignKey('UserProfile', related_name='books')
Another question you will run into is how to update and/or display those nested relations in your serializers.
This FAQ article from the django-restauth docs and this chapter of the official django-rest_framework docs will get you jumpstarted.
Best,
D

Django user with custom data in multiple apps

Customer User models was great but if you want to build a project combining multiple apps, each app can assume it's going to have the user model as part of it's models. My plan is to revert to the standard django User and have a profile in each app.
eg.
app1.models.py
from django.contrib.auth.models import User
Class App1User(models.Model):
user = models.OneToOne(User)
special = models.CharField( some field that relates to the user in this app)
app2.models.py
from django.contrib.auth.models import User
Class App2User(models.Model):
user = models.OneToOne(User)
another = models.CharField( some field that relates to the user in this app)
etc.
Then add code to go and get the relevant profile data when needed, maybe adding some middleware or template context processors. Before I go down this route I wanted to check this is the most Djangoeque solution?
Imho yes, you doing it in the right way.
And you don't need any middleware or context processors to get relevant data for the user. OneToOne field is easily accessible as the attribute of the user instance:
{{ user.app1user.special }}
{{ user.app2user.another }}

add an image field to admin.auth admin site in django

Hi ive not be able to find any one trying to solve this issue yet so i thought id ask the question here. Basically im trying to add an image field to the admin.auth users admin site that relates to my userprofile model.
Aswell as users that register to the site, the admins need to be able to specify a profile picture when the create a user in the admin site that will be used for posts they make to news and blogs etc.
Is this at all possible, i have the userprofile model working which will allow me to add the image but i want to include this in the admin user panel when an admin creates a new user.
Any help is greatly appreciated!!
Thanks in advance
You can add your UserProfile (with the extra image field) as an inline to the User adminModel. So when you go to the admin.auth panel to add a new user, there will be an inline below it with all the UserProfile fields.
Something like this should do it (in admin.py of whatever app your userprofile is in):
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.contrib import admin
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserModelAdmin(UserAdmin):
inlines = [UserProfileInline,]
admin.site.unregister(User)
admin.site.register(User,UserModelAdmin)