Django Custom User Model | Example 1 | Multiple User Types | Django AbstractUser

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to the django rm mastery course   in this tutorial we learn how to create a set  of tables models to support multiple user types   if you are looking for a django course and  you want to master building and interacting   with databases with the django project then  please consider our course here now you will   find a link in the video description that should  always give you the best price for the course   this is example one because there are multiple  approaches to fulfill this type of requirement   much of it will actually depend on your particular  project and your particular project requirements   because of that i have generated some  specifications that we're going to be working with   so you can see here that our design is going  to support a user who can only have one role   so they're either going to be an admin user  a student user or a teacher user now i would   say this is fairly common a lot of systems out  there will only support one user role so you'd   have to have a separate account as a student and  then a separate account as a teacher for example   ultimately this approach does make it a whole lot  easier to manage your application and design and   build your application the second specification  here and we talk about this a bit later the user   cannot change their role so once they have been  defined as a student they cannot then go ahead   and change their role to a teacher so once they  have a student account that's their student   account they need to sign up as a teacher to have  a separate teacher account and a teacher role   needless to say you can change student  and teacher to kind of fit your scenario   so third of all with a star students and  teachers require separate profile data in   this tutorial we are going to lead towards  this idea of creating separate tables for   students and teachers or other users or roles to  allow them to separate their profile data because   what we store about the teacher might be separate  to what we store about the student for example   before we start building let me just give you  a quick overview regarding authentication and   authorization so these are two vital information  security processes that administrate and protect   your system and information now django  supports out of the box but if it comes with   an authorization uh package if you like or tools  and then it also comes with authentication so   we have been predominantly focusing in this  section regarding the authentication so actually   authenticating the user and obviously that data is  authenticated based upon the username and password   in the user table so let's imagine we just  built a table a user table with just username   password and roll and we could specify multiple  roles so what we end up with is potentially   lots of users and they're assigned to different  roles so in order to authenticate them um we just   need to know their username and password and then  to authorize them so it's slightly different so   one step is to make sure they are who they are  by their username and password but actually in   the application we want to be able to authorize  them to perform certain things so what we can do   here is that we could use the role of the student  that's assigned to that particular user to then   authorize them authorization maybe to certain  pages or application or to access certain data   so very simply we could have for example if role  equals student then we could allow that user to   do something but of course that user first of all  needs to be authenticated they need to be actually   logged in with a username and password now django  does support or does provide both authorization   and authentication so behind the scenes  whenever we generate a new user potentially   what's assigned to that user are permissions  if you look at a default django project   navigate to the database you can see there is a  number of tables here and that all supports the   authentication and authorization process so here  we have some groups and some permissions so django   when we create a new user will assign  potentially permissions to that user   so you can see some of the different permissions  here that we can apply by default so for example   change group delete group add session delete  user change user so these are all permissions   that have been set that can be applied to a  user so let's imagine we created a new user   that user logs in authenticates themselves with  the username and password and then we can assign these permissions to that user so let's assign the  add user permission to that user that means they   potentially will be able to log into the admin  and then add a new user because they have this   permission here so hopefully you can start  to see that so here we have authentication   like i said once they've been authenticated  we could use information in the user table   to then perform actions based upon their role  so if they are a student we could check that   and then allow them to a certain page for example  allow them certain data if their role is a teacher   obviously they have different uh different  permissions uh they'll be authorized to look   at different data and so on so we could use this  in the user table now the other approach is to   by all means create roles for particular users but  what we could do in terms of authorization is that   we could utilize for example a a group so what  we can do here is we can set up multiple groups   so the user logs in and then they are that user  is assigned to a particular group so if we were   to make for example two groups we could assign  that user to a particular group depending whether   student and teacher and then what we can do based  upon those groups is we could set permissions   define permissions student is allowed to view  this and view that teacher is allowed to delete   this and delete that we could build these  permissions and assign these permissions to   groups now remember users are associated to groups  and permissions are associated groups so what we   can now do in our application for example is we  could check what user the group is in and then   we could check what permissions they potentially  have so it just allows us to without having to   define so much information in the user table  it allows us to expand the permissions that we   can define to every user and we can manage  users not by the data in the user table by   the fact that they are in particular groups and  we assign permissions to groups so one of the   main reasons of assigning permissions to groups  and not users is a lot easier to manage imagine   you had a thousand users and trying to manage a  thousand users and their permissions is quite hard   if we would update one permission we would  need to update that one permission for   every single user potentially and so it gets  a little bit messy so by adding users into one   or more groups it means that we can manage their  permissions whilst they're using the application   so one of the main reasons of trying to explain  that to you is because a lot of students   would start off by creating two tables one  for student and maybe then one for teacher   but hopefully you can start to see that isn't  needed because if we have one table there is   common information related to those all the  users and that's their username and password   so that doesn't differentiate between different  users at all that's exactly the same so in actual   fact what we could do is just build a user table  with username and password and we could manage the   role their individual roles by assigning  that particular user to different groups   based upon what type of role that they should  have in our application so in actual fact we   don't need a separate field here called role at  all we could just simply use authorization groups so there's absolutely no need for us to set up  multiple tables for multiple user types or roles   so i mentioned earlier that we didn't need role  because we could manage these users in groups   but that's a bit of a nightmare imagine we didn't  have the role field in our table so when we use   set up the user we didn't find define their  role what would happen is that we have loads of   users in groups and for example how would i know  whether that teacher is an actual teacher or not   i would have to ask someone else or find  out some information so in order to manage   those users more effectively it probably  is better for us to actually define a role   in the user table to make it easier  for us to identify that particular user   and utilize that to maybe assign  them automatically into groups okay so into the code you will find a base  zip file you'll be able to extract that and   then just delete that extract that that  will then provide you all the setup code   and we're going to work from there so here we  have the core project we have a user folder here   so we're going to go into the models and start  building our database so we'll make the general   assumption that you maybe have seen the previous  tutorials in this mini series i've created in this   course there is a link in the video description  to the playlist for this course so the approach   we're taking here we are going to be utilizing a  custom user model now this is highly recommended   whenever you set up any django application that  you don't use the default user model that you just   extend potentially using using the abstract  user so i'm just going to bring in the code   apologies i know that some people get annoyed with  just copy and pasting but it gives me time to then   just explain rather than watch me type because i'm  terrible at typing and talking at the same time   right so abstract user so like i  said this is going to allow us to   override or allow us to utilize our own user table  it's taken all the information from the default   user table that would been set up and we  migrated our project at the start so we're just   building a copy essentially of the user table  that will include all the fields and all and   any methods and anything else associated to the  user table so it'll work exactly the same way   as the normal user table so let's go ahead and  build a new user table so we'll just call this   user why not because there aren't any other  tables called user because we're going to be   utilizing this user table so let's bring an  abstract user so we're just going to inherit   or and now kind of override maybe some of  these settings from the default user table   okay so let's set up some roles so there is a  tutorial where i explain um different methods   or different approaches to creating  what is a choice field so models dot   text choices so let's set up our different users  so admin equals admin um so this is going to be   stored in the database the word admin and then the  human readable word for any drop-downs that this   is associated to let's just go for the name admin  so that's what's going to be seen in the drop down   so student equals same thing again  student and then the human readable so you get the idea now so i've added the teacher  as well right so what we're going to do is we're   going to set this oh actually um that's just an  example so let's just keep it simple so teacher   there we go right so i'm going to set the base  roll so whenever a user signs up uh the base   row is going to be admin now already you might  be flagging uh in your head why would they be   admin just a normal sign up here i'll explain  that later why we're going to set admin here   and it's something you might want to change but  the workflow for this application um is going to   be that if if a student does want to sign up i'm  making the assumption and i won't go through this   in this tutorial i'm making the assumption there  is a separate form for student and i'll show you   how to create a separate abstract class so that  we can work through an abstract student class when   building a student and the same for the deferred  teacher so if his teacher was to be signed up to   this system then i'm making the assumption  that this teacher would go to the teacher   register page and sign up through that and  again we'll build a an abstract class for that   otherwise um anyone else who signs up  to this system will be an admin user so   therefore i've set the base role to admin so  role here is referring to this subclass here   and then obviously the admin data right so  with that in place uh let's now build a new   field if this doesn't make sense to you obviously  what we've done is we've inherited everything from   the user table and now i'm adding a new field  which is called roll so models dot and i need   to decide what type of data i'm storing it's going  to be a character field and then i can set the uh   the human readable name for it or not  and then let's just go for the max length   max lent um equals 50 and then we need to choose  or define our choices so we need to connect our   choices here to our field so let's do that  choices equals and this is going to be roll   that's the name of the class roll and dot and  then we just need to then add the word choices there we go if we were to look in the admin  now at this we would see that the user   if we were to add a user we would see that the  user would have a role associated to them now   it's important to remember here potentially that  if we are going to build a new user we want to   assign him to a role i think um or at least i'm  making that constraint in my mind for my system   and this is why i haven't set this to um no  for example because i do want it to make this a   mandatory field when the user signs up now because  of that potentially i'm now considering that   maybe i need to create a separate workflow for my  registration in that case potentially i'm thinking   about avoiding using abstract user and potentially  working an approach whereby i set up a custom   workflow for registering users now it just happens  that the next tutorial we will be focusing on that   and that's the reason why in the preview i set  up that little star to indicate that students and   teachers require separate profile data because  that's something really we need to tackle um   by potentially creating our own sign up workflow  and like i said we'll do that in the next tutorial   right so here what i'm going to do is in actual  fact set up a custom workflow and i'm going to   override the save so what i'm going to do here is  override uh the save method and then i'm going to   set the default role to a user should they sign  up so because i haven't set the role field here   to allow null fields for example when a user does  sign up in this case just the admin users this is   all about the admin really then we are going to  need to assign something to that field so i can   actually do that without making a custom sign  up process um or overriding anything there by   utilizing the save function here so if not self.pk  so if the user doesn't have a primary key if the   user hasn't been created then we're going to say  self.roll equals self dot base roll so we're going   to assign them to the base roll which is admin and  then we just need to return that and save so super dot save and then just pass in arcs and quarks a bit of silence okay on a side note if you're not too  sure what args and quags are for example   there is a good tutorial in this channel  which will help you understand that in a   little bit more detail all right so let's give  this a go let's go ahead and migrate this uh   make migration oh actually we can't do that  here can we so let's go into the setting we   have created our own user table so we need  to tell django that we're utilizing that   settings i think i've already done it yeah  so in the settings here at the bottom you   also use a model user that's the app or the  label and then the user table so i've added   that into django so i'm going to tell django  that i'm using this table so make migrations and then go ahead and migrate and see what  we've got so here i've got the sqlite app   extension installed so i can then go ahead and  have a look at my tables and you can see here i've   created a new table user user so inside of here's  all the user tables you'd expect to see except   for we now have row defined so what we should now  be able to do is add a new user now remember the   default setting if we add a new user will be for  the admin user so let's go ahead and py python 3   create super user so if we create a new cpu user  we should be able to no password is too similar   to your name blah oh yes okay so it says here that  args is not defined looks like i've got a an error   there so there's a bit of a typo there apologies  so let's just do that again create cpuser and there we go so if i look in my actual table  at the data we can see that we have created a   new user and further along here a little bit we  should have the role which is admin so if you're   wondering why we set the base role to admin we'll  see as we go along i realize it's probably not the   best choice but let's just go through this process  and we'll come back to that right so next up then   imagine we wanted to register a student user so we  could better handle that by creating a new class   a proxy class here this means that this class  this table won't get generated but we could work   through this table when working with student data  so for example here we could set up a new manager   and apply that manager to this class  so that whenever we utilize this proxy   model here to run queries for example  we're always working on the student data   so you can see what i've done here we've inherited  user and then we've override the base role   so if we were working with this model you can  see that the default role would be student so   we set the class to proxy true and then  of course what we could do is we could   add other functions here and let's just uh  create a welcome so this function would be   purely for a a student with the role of student  for example i think i said that right so   this function would be for a student with the role  of student only for students just as a bad example   right so with that in place what we can now do  let's go into the well let's uh migrate this so we make migrations and we'll go ahead and migrate okay so now we can go  ahead and python three manage to pi   let's go into the shell so what we're going to do  now is just run a query to actually create a new   student user so we'll see how this can be utilized  right so from user dot models let's import student so the point here is that if we were going to  create a new form for students to sign up to   the system that form will be connected to this  student class is proxy this meta class here and   by doing that the base role will be up will  be changed to student and we anything else   in defined in here would be also applied when we  do sign up so let's go ahead and now say student   dot objects dot uh create so we're going  to create a new user uh create user produce   so let's go for we need the default  username equals just go for one s1   and then the other mandatory of  course is the password password equals password and yeah that's pretty much uh all  we need to do here so let's go ahead and add   a new student you can see it has been added  let's go into the user table and see if their   base role has changed um show table well we it's  not that one and there we go so we have a new user   that's the username s1 and we can see that  their role is now student so let's go ahead   and build a manager now i'm just going to bring  this code in you'll see this in the final code   example which you can download from this video  description so here i've created a student manager   you can see here what we're doing is  we're just filtering out the users   with the role student so inside the user table  go into the role of the student so their role   must equal student here in order to return  any data so we attach this manager to our to our student model here student equals  student manager so whenever i query   the student oh do you want to do that  whenever i query the student table so   i would need to query like student  dot student um let's go for all and no actually student oh because  okay kiki okay um let me just exit this   let's go back in so exit come back out again  let's bring in student let's go ahead and   query for all the students and you  can see it returns one student so   if i were to for example uh want to work  with any student data then i'd obviously   utilize this manager and that would  filter out all the users in the table   um so if i were to for example change this i'm  just thinking on my feet then what i need to do   if i say objects dot all you can see it returns  everyone from the user table and i obviously   only want to work with student data so this  manager basically will filter out all the users   to return only users and we could then filter  further based upon all the students so obviously   we have students and teachers so i could just  copy and paste this and change the name right   so if i wanted to work with the student with the  staff sorry then i could change this to or teacher   the teacher manager and i can change this class  and to teacher user so i've just copied and pasted   and now i'm just changing this so their role  would be teacher so i just need to update that and then we call this teacher and this  would be the teacher manager only for aim for teachers i think we've done that so let's  go ahead and try and add a new teacher we can do   that through the cheat teacher proxy class here  hopefully you get the idea by now so i'll quickly   run through this migrate and then let's quickly  go into the shell it's not the shell okay python django shell so go ahead and from using models let's import  teacher now and then we go ahead and add a teacher   so again it's going to be the same process so i'm  just going to copy and paste this in so teacher   great username and then password to give that a  go and see that a teacher has now been created   so let's go into the user and have a look  you can see that we have the new user it's   a teacher user and we can check that by  looking at the end we now have teacher   so far then we've created our our roles  admin student or teacher so we're able to   kind of register these three different roles  we've then gone ahead and made the assumption   that the user cannot change their role so once  they've set up their account that's their role   if they need to set up a if they are a teacher and  they want to become a student and vice versa then   they need to create a separate account for student  or teacher so that's how we set up this so far   so let's now think about students and teacher  which requires a separate profile which requires   separate profile data now here remember this  is all about the fact that if you are a teacher   you're going to be a teacher you're never going to  be anything else unless you sign up separately for   a student and so on so this will work okay for  that type of approach so let's build a profile   table for both the student and teachers so we  saw this in a previous example where we created a   a one-to-one table to use us and we could take  that approach now and do exactly the same thing   so let's go ahead and do exactly that so i'm  just going to bring in the code so here um let's uh let's just exit this very quickly  if you haven't started to utilize formatting   tools let's pip install black so that's going  to format our code um trying to follow the pip well once black's installed  just go ahead and python three   black and oh no here's the m flip switch black and then dot refer to all so that should format   everything there we go right so  right now student so underneath   the student here we're going to create a a  one-to-one model uh so you can see here that we have two fields the first field is the  one-to-one connection to the user table   and then secondly we're just going to create  a random thing so here we're going to have   student id we're going to set this to null and  blank equals true so this can be a null field   obviously you might want to change that  and so on just for the purpose of this   and whatever we're saving it's just really as  a demonstration you might want to add other   profile data right so now we've attached that  to the user table what we're going to need to do   is when we create a new user a new student we  are also going to need to populate this table   so we have seen this in the previous tutorial  we did this by utilizing a the django's signals   so we're going to use the post save  signal so whenever we save some data   whenever we save a new user we're going to  send a signal and capture that signal so   that we can then perform some additional tasks  so we're going to need to bring in the receiver   so we can receive those signals let's go  back down here so underneath the student   what we're going to do here i'm just going to  bring in some code so this is going to and like   i said this is what we did in the previous in  a previous tutorial uh we created a receiver so   what's important here is that the sender is  student if we are going to be working through   student with any student queries that we run  so we are going to say the sender here student   so whenever we save a new student this is going  to be captured by our receiver here and then   we're going to perform some additional actions so  the additional action that we're going to perform   here is that if the user has been created  we're going to set their role to student   now sorry if they apologies if for example  the user has been created correctly   we're going to check to see if their role is  student just an additional check and then what   we're going to do here is we're going to grab our  one-to-one table student profile and then we're   going to create a new entry with the data that  we've used to create that new user so we create an   instance a connection from this table we create a  new row which is associated to that new user that   we've just created so that's how we're going to  populate our one-to-one field so it is critical   that we're following this now because if you  remember i said users cannot change their role   because that's where it gets a little  bit more involved because if the user   is allowed to change their role or  have multiple roles then potentially   anytime they change their role we need to  do something with this data so if we do   add a new student and then automatically  add a new profile table for that student   if the student were to change their role what are  we going to do with that data because a lot of me   is telling me well actually we probably need to  store that data for some time maybe there's a   in your country you've got data protection rules  and so on so there's lots of different standards   and so on which will potentially require us to  do that so what we're going to do with our data   and of course we would need to then set up  a trigger potentially to then create a new   teacher profile for that user too so there's some  questions there that we need answering depending   on how you want to set up your application but  here we're making the assumption that once you're   a student you're a student and that's it if you're  if you don't want to be a student anymore then we   simply just delete everything and that's how  it's going to work now because we are using a   one-to-one table go back into the code you can see  we're using cascade so if we do delete the user   then what should happen is that their  student profile data should also be deleted   okay so i think i think that's pretty much all  we need to do so hopefully that makes sense um so   yeah let's give it a go i guess so python  3 managed to pi let's go into the shell   uh same process again let's bring in the  student table now i say that let's exit that   because because we haven't migrated yet a step  too far step too far right so python three   matched up by make migrations and let's go ahead  and migrate you can see that the data will work   absolutely fine with the previous two students  we created um they simply won't have profiles and   that is another potential issue here the fact  that if for example we do save a user if the   user does get saved and there's an error we're  storing this data then we've got problems and   that's where potentially the next approach in the  next tutorial allows us to customize this process   because potentially here we want to make sure  we want to make a maybe an atomic transaction   so that whenever we store student or create a new  student user we also want to update their profile   we want to do that together so if one of those  were to fail either creating a new user or profile   then everything fails so we can't necessarily do  it here very easily at this point so that kind of   feeds into the next tutorial right so yeah we've  just migrated so let's go into the shell let's uh   bring up the student model again and let's add now  a new student so i'll just copy and paste this in   let's grab a new student so student objects.create  user some basic information so the user has been   created so let's go ahead and look at our tables  so we'll make the assumption that has been created   so let's have a look at the profile and we should  have a student profile table let's show the table and you can see there we've created our new entry now of course we can do exactly the same thing  with the teacher of course so we can go ahead   and create a teacher profile table so let's do  that under here so this is our teacher profile   table and of course then we can set up a separate  a receiver for that again it's just a copy and   paste i've changed the sender to teacher and  then all the other details here to teach her to   update the teacher profile so that's all in place  and that's going to work in the exact same way   so i won't go through the process  of migrating that etc you can just   have a look yourself and give that a go but that's  going to be exactly the same so the code for this   is in the download in the video description go  ahead and download the code take a look have   a go don't forget the specifications that we're  using in this tutorial well i do hope that's given   you something to think about there i was thinking  about taking down the path of creating new groups   based upon the user when they sign up i think i'll  do that in the next or a following tutorial that   seems like a good approach to take and like  i said we are going to be building on this   idea and making it a little bit more complex and  complete so we'll eventually add that into the mix   thank you very much for listening if you have  got this far right to the end there won't be   many students who would have gone all this way  so i do appreciate your support and i do hope   this was useful it's always good to get your  feedback because until i get your feedback um   i just continue doing what i'm doing although i  tend to not like many of the tutorials i create   i tend to talk a little bit too much  potentially and so on at least in my opinion   it's always good to get your opinion to know  exactly how you feel even if it's negative um   or you feel as though it's negative i'm not going  to be taking any offense to it i simply just need   to know in real terms whether things are very  useful or not thank you very much for listening
Info
Channel: Very Academy
Views: 20,803
Rating: undefined out of 5
Keywords: Django Custom User Model, django model, django example, learn django, Django User database, django, django extend user model, custom user model django
Id: Z6QMPAcS6E8
Channel Id: undefined
Length: 35min 37sec (2137 seconds)
Published: Sat Jul 16 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.