So, I am fairly new to Django and I know there is just one User type. I am wondering what is the best way for me to go about setting up my models.
My site needs 4 different types of users: admins (including superuser), teachers, students, parents. I want only admin to be able to use the built in admin UI. I want teachers to have some admin features but only on frontend UI.
So far I have extended AbstractBaseUser and BaseUserManager to create users that can be assigned the 4 roles mentioned above and a few different things. They are working and I can manage authorization of page views with them, but this is just scratching the surface of what I hope to do.
But how do I manage this when I want a teacher to have many students in a class and only see those students when they login? I want these students to be assigned to teacher by the admin and then allow the teacher to have some permissions with the student info.
Can I use signals to create a Teacher model that belongs to aUser with a role of teacher and that same Teacher model has_many``Students. The ``Student would also have been created instantly with the User having a role of student.
I am thinking along the lines of how you would create a Profile with a new User.
I know how to associate Teachers and Students and Parents, etc but it is confusing to me when they are all user types as well.
Or is there a way to do this with just keeping them as ``Users``` with roles and relating them in another way?
Thanks for the help.
Why don't you try this :-
https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html
I think this is the answer you are looking for.
Let me know if you need further explanation.
Happy coding :-)
Related
I am new to Django so please bear with me if my questions seem too basic.
So, I want to create a web app for a kind of a store in which I have three different kinds of users.
Admin(Not Superuser) who can:
create, view, update, delete account for a Seller(agent)
issue them inventory
Seller who can:
sell an inventory item to a Customer(customers cannot themselves purchase it, only the seller can do it by filling in a form)
a Customer account should automatically be created upon submission of the form by Seller or if the Customer already has an account, the purchase should be added to their account
Customer
can login and view their account
What would be the best way to go about it? Using auth Groups, Profile models or anything else?
Any help would be wonderful. If something is not very clear in the question, I can provide more details. Thanks.
Django already has a solution for this: a Group [Django-doc]. A user can belong to zero, one or more groups. A group can have zero, one or more Permissions [Django-doc].
These permissions can be defined by a Django model, for example for all models there are permissions, to view, add, change, and delete objects of a certain model, but you can define custom permissions as well, for example to visit a certain page. A user then has such permission if there is at least one group they are a member of that has such permission.
You can work for example with the #permission_required decorator [Django-doc], or the PermissionRequiredMixin [Django-doc] to enforce that only users that have the required permission(s) can see the given page.
You thus can make groups for a seller, customer, etc. Often people can have multiple roles, for exame being both a seller and a customer which thus is elegantly solved through the permission framework.
I am currently learning Django, specifically DRF to make an API that will be consumed by a web app client. The app is for a teacher who gives extracurricular classes in Mathematics and Science. My basic idea is that there will be two types of User, a Student and a Teacher. Teachers will obviously have more access rights than Students. The problem is, a django User class has the is_admin attribute and, since only Teachers could possibly be admin of the site, I cannot create a single User class that has is_admin and user_type attribute. For instance, the User with is_admin=True and user_type=Student will be an invalid combination. My idea is to make my User class as an Abstract Base Class and then make two seperate classes, Student and Teacher, that inherit from it. This is also ideal in the sense that only Teachers can publish articles, which means the Student class just won't have that permission, but then I face another problem. All Users have a single Profile. The Profile will store a bio, an avatar image of the user, etc. But when setting up the OneToOneField relationship in Profile, the profile must have that relationship with Students and Teachers, thus all User types. How can I set up that relationship? Can I say OneToOneField(User) and due to the inheritance that user could be a Student or a Teacher? If not, what should I do?
If you have experience and you are thinking, why on earth is he (that is me) doing that?, feel free to comment on my design plan and please show me how a better design would look. Thanks in advance.
EDIT: Is there any advantage in having a single profile for each user, storing a bio and image etc? Is there any gain in this over storing that info in the User model?
Don't create separate classes. Just that they have different permissions doesn't mean they need to be different classes! They can all be User (or your own subclass of that, but the same).
Then you configure two different groups (docs). You assign each new user to one of the two groups.
Your code can then use some custom permission (say a 'publish' permission on Article) and give that permission to the Teacher group, and check in your code that the current user has that permission.
Typically only one or a few users have "is_admin", is_admin means that you automatically have all existing permissions. It's for user management, configuring the groups, and such.
Keep it as one class unless you need each class to have different attributes. But in your case, you can just make is_staff=True synonymous with being a teacher, and then you could get rid of the user_type attribute. It's usually better practice to use boolean fields instead of char fields with a finite set of choices that do unknown things in the code. So staff would be teachers, and non-staff would be students.
Aside: By "is_admin", you meant "is_staff", right? I am not aware that the django User model has an "is_admin" attribute, only is_staff and is_superuser.
I'm trying to make my first django app (a dating site) that consist of varying user models.
Users need to have fields like location,language,religion, height, preferences, family details horoscope etc.
Staff/Agency - users added by Admin from the panel - some contact details like address,phone etc would be enough. No self registration required.
I prefer to have email-id as the USERNAME field.
Can someone please guide me how do I proceed to make User models in this case? I have been struggling to follow the docs and various thread on forums to get some light.
Any help would be highly appreciated.
Thanks.
You should 'extend' the django user class by creating a one to one model, generally called a profile that contains the rest of the information you need to gather on a person.
It is considered bad practise and difficult to extend djangos user class directly.
Have a look at this youtube video, it's a bit out of date so don't copy it word for word, but it gets the general concept across.
https://www.youtube.com/watch?v=qLRxkStiaUg
So I want to keep track of about 100 employees but only five of them should be able to log in into the backend (the rest starts with no loginpossibilities at all) what's the best way to solve that problem ?
I thought of an EmployeeModel that has a 1to1-relation to an abstractBaseUser but is that the way to go or is there something easier ?
~Max
Why not make use of Django 1.5's new customisable User model and model each employee as a user with an extended profile:
In Django 1.5, you can now use your own model as the store for user-related data. If your project needs a username with more than 30 characters, or if you want to store user’s names in a format other than first name/last name, or you want to put custom profile information onto your User object, you can now do so.
By making each employee a "user", you have the balance of being able to control their ability to login (using is_staff) as well as being able to add as much employee profile information that you need.
Why not just have FK from employee to user if an employee has an attached account?
Don't go for over customisation as this can be easily achieved easily using the built-in tools. Make the login_page require a permission suppose say "can login". And just make these 5 users have those permission. So rest will automatically get a permission denied response when trying to login.
I have developed an app for school management. Teachers and others roles have an account (django user) to control student attendance, Behaviors issues, etc.
Student is a model itself. Teacher is a User proxy.
At this moment I'm ready to extend the app to allow parents access to children information (is cruel, but for the sake of students ;)
I'm evaluating this alternatives:
Make a simple php app only for parent access (with dedicated db user
and views). It seems secure but I don't like php.
Add a password field to Student model and build my owner authentication system. I
don't like to have a 'django authenticated student'.
Integrating Student authentication with actual auth schema. I don't like this for
security reason, this means to check all views security, and this mix teachers and students.
Create a new django application only for students (and parents) with two databases, the 'school' database and a new one with auth for students
What is for you the best way to authenticate parents before to see children information?
Any suggestions are wellcome. Thanks a lot.
Ah! I think that is easy that parents forgot passwords.
School has over 800 students, app store more than 1milion of presence cheks for year, lot of Parents interviews, ...
Django contrib.auth models incorporate groups and permissions in addition to user accounts. In fact regular django users and django admin users share the same model only with different permissions.
Considering, the default authentication model (from a security standpoint) is already shared with much bigger consequences in case of a breach, I don't see a reason why you shouldn't have students authenticate with the same model and just assign them into a separate group and manage their permissions. Your security will not be worse or better from what it already is.
As far as development side goes, all you have to do is simply use decorators on the view handlers which are Teachers/Parents only to limit student access to them.
See: Permissions decorator
If for whatever reason this is unacceptible (although I cannot surmise a reason from what you said), you will have to do either:
Write your own middleware that injects itself into contrib.auth (reinvent the wheel)
Use an external system to verify permissions (completely orthogonal to Django's approach and will actually complicate your system much more than to use integrated contrib.auth)
Additional down side to doing your own authentication system is that you now have to worry about all kind of security issues that Django solves for you (like CSRF protection, SQL injection/escaping and many others). Not to mention bugs that can creep in vs. using tested and proven code/model provided by contrib.auth.