Placeholder Image

Subtitles section Play video

  • welcome to the start of a new tutorial, Siri's, and this is called Teach Me Jenga, which is a project built with Django and react, showing you how you can work with multiple users in a kind of mock online system where you can create assignments, filled them in and see the results of those assignments on your profile.

  • And so this is the finished product off that project, and what I'm going to do is just walk you through what it looks like.

  • So you get an idea of what we're actually working towards in this tutorial, Siri's.

  • So I'm gonna go ahead and log in, and I already have a user created for this, and we don't have any assignments just yet, so we'll go ahead and create one so we'll give it a title.

  • As this is, the first assignment will set the question to be.

  • Is the school well, so the answer is yes.

  • And then we'll add a choice where the 1st 1 could be Yes, and the 2nd 1 can be no.

  • And then we can have a question, and I'll say, this one is Django is awesome.

  • We'll say the answer is true.

  • then the choices are true and false.

  • And then we can submit this.

  • And now we have our assignments, an assignment that is loaded here.

  • Everything click on it and we see we get the questions.

  • Yeah, and we've only got two questions.

  • So we've got is the school will say Yes, Go to the next one.

  • We'll see.

  • Django is awesome.

  • And let's say I want to go back and I'm actually gonna change my mind.

  • Several ST No, this isn't cool.

  • Go forward, jangles.

  • Awesome will say true everything.

  • Click, submit.

  • And if we head over to our profile, you can see we've got 50% for that assignment.

  • And that's because we said that jangles not cool.

  • Where's the answer was yes, it actually is cool.

  • And so before judging how complete this project is in terms of validation and seeing detail, views and thinking, there's a lot more stuff to be displayed and that this is really just too basic.

  • You'll be surprised as to how much actually goes on in the back in to get this to work.

  • And so we're going to be jumping into ah whole lot of customization of serialize er's and a lot of reactors.

  • Well, so this is what we're going to be building in this project way.

  • The two different kinds of users were looking at our students and teachers.

  • Only teachers can actually create these assignments, and only students in theory should be allowed to answer these sons.

  • And so we're gonna walk you through the process of creating this multiple users system.

  • And let's get started with it now.

  • So to get started, you're going to want to open up V s code.

  • I've got absolutely nothing here, an empty directory which we'll use to store all the project content and get started actually going to clone something from our get up Paige.

  • And this is a boilerplate project that we created for getting started with Django and react.

  • And that is here.

  • The Jenga react boilerplate.

  • And this is just to help getting started with adding projects that a bolt with Django and react because it seems we're going to be doing this for quite a while.

  • So I'm just going to grab this year l here and going to clone into this depository so we'll just say, get clone.

  • And that will bring this repositories into this folder, and today we have it.

  • We've got the V s code project settings.

  • We've got home directory, which is basically our Django project, and we're currently using three different settings files, depending on whether you're in production or development.

  • And then we have a source folder which has a basic react project set up a swell.

  • Now I'll link a video showing you everything that's contained inside this project, which recovered in one of our videos, showing you how to set up with indication between Jango and react.

  • So everything in that video we basically took and just compiled it into a boilerplate repositories so that we could just pull that easily so we don't have to keep on repeating ourselves that way.

  • We already have a nice set up to get started with, and we can get working from here.

  • So what I'm going to do is just bring all of the folder contents inside this directory that I'm working with and there we go.

  • Now I'll just clear out the terminal and we can take a look at what we've got.

  • We've got TVs, code settings, which basically is just sitting pilot and the python part of Virtual environment path and some files to exclude.

  • In obvious code editor, we've got the Home directory which has a base settings for all the installed abs, middle way templates and some other things that will need for both development and production and then in development.

  • You've got the allowed hosts being our local host, debug being true.

  • The W s job application for development and a DBS collect three daughter base set up with the local host off 3000 being in our course origin White list and then in production, we've got our domain withdrew.

  • Need to add the different Ws July application for production a daughter base set up for post grace which we don't actually have those credentials set up just yet.

  • But we've got the configuration.

  • They we've got orthe password validators and static file storage for when we use white noise.

  • And this is all with the intention to eventually hostess on Hiroko.

  • That's why we have a profile here.

  • But we'll get into that towards the end.

  • So we also have the source folder which currently has ah, wrap dress which is water trying to sign up.

  • We're using react redox hence these maps, state props and map dispatch methods that were connecting to our app.

  • We've got a higher order component which basically returns the Children off the props that up Austin.

  • And we've just got a layout, a log in and a sign up container which again also comes from that video tutorial on authentication with Django and react.

  • And so what we want to achieve in this video is basically to set up the Jang arrest framework arrest orthe, which is what we're going to use to authenticate uses on the back end.

  • But we're going to need to customize that if we want to actually have our own custom user.

  • So we're going to create our user.

  • We're gonna create the serialize is for that user and show you how you can customize the rest orthe to allow for those users.

  • So we'll get started by opening up the terminal and just creating ourselves a virtual environment which will just name virtually envy.

  • And there it is.

  • We can activate that and we'll say, Put in stole, dash our requirements dot t x t and we'll open up another terminal here to install on no dependency.

  • So just run in P.

  • M.

  • I.

  • And we can get started with creating ourselves a users app, and this is where we're going to create our custom user.

  • So it's a python managed up.

  • I start app and will say the name is users and we can go into our home directory to settings based on pie and inside the installed APS, weaken, scroll down and add our users.

  • And with that, we can close based on pie, and we'll go into our users Appiah and we're going to the models.

  • And what we're going to do is import the abstract user, which comes from Jang Go's contra orthe models.

  • So we'll say from Django that contract that oft of models import the abstract user.

  • I'll see you get two types of users that are prompted.

  • One is the base using one's the abstract user.

  • Now the abstract base user will require a lot more configuration.

  • Have also covered this in another video where we actually used the abstract base user to create our own custom user and show you how you can link that up to be the default user of your sight.

  • Whereas if you use the abstract user.

  • It's actually a lot simpler, so we're going to go ahead and use that.

  • We'll add close you and called us the user, which inherits from the abstract user.

  • And basically what this means is that it has all those attributes like username, password, email.

  • All of that configuration has done for you.

  • Except now you can add the fields that you particularly want to actually add that will make your users that much more unique.

  • Now, in our case, we're going to store two kinds of users.

  • We're going to have a student and a teacher.

  • You could be both at the same time, but we're not too worried about that.

  • And so the way that we're going to handle that is by adding two fields on the user, and he's going to be Boolean Fields.

  • So we're going to have the Is Student, which will be models dot boolean Field.

  • So either true or false, and then we'll have the is teacher, which is also a model's dot brilliant field.

  • So that means is that when we create the user, we're going to need to pass in whether this user is a student, so either true or false and reading to Parson.

  • If it's a teacher and they will just say define the string method, which takes himself and also return self dog used name because remember, this doesn't hear it from the abstract user that is our base user, and that is what will be using when we create our users.

  • Now what I'm also going to do is define another classier, which is thief student, and this will just be a model stop model.

  • And all we're doing is basically a signing a 1 to 1 field with the user, so that instead of working with the base user that we created here, will work with student model when we need to refer to a an actual student.

  • And we're not going to add too much configuration to this model.

  • But it's just a little bit more convenient because here on the student, you could then passing a lot more other fields, like what classrooms they belong to, what grade they're in, et cetera.

  • You could do a whole bunch of things like that.

  • We as the user, you just want to define whether that uses a student or a teacher.

  • That's the whole purpose off.

  • This model here will just say that the user equals to a 1 to 1 field with the user that we just created here and will say on delete equals two models dot cascade so that if the user is pleated, then their student is to lead it as well.

  • And then we'll just say Define string, which takes himself and say Return self dot user dot e mail, for example, or using it.

  • We could do as well and so that we then need to go Intel Django that our default user is actually inside out users app.

  • So we're going to go into the home directory to settings based on pie, and we go all the way to the bottom here, and we'll just say that the oath user model equals two uses dot user.

  • So basically what it's saying is look inside, users don't models and find the user model that is our default.

  • Or use a model to use when authenticating users animus against had one was sitting here, which is for unique emails.

  • So will say that the account, unique email equals two.

  • True, Basically, this will ensure that we don't get any duplicate e mails off our users and like that weaken now try and make migrations so we'll just bring up the terminal will say, manager pie, make migrations and we see we get create model user and create model student.

  • And then we'll say, managed a pie migrate to actually migrate those and we also get the base migrations for the entire project.

  • And now, if we were to try and create a super user, then you'll see that you'll actually run into an era because it's going to use our custom user, which has two extra fields on it.

  • So it's going to tell you that is, student cannot be null, and his teacher cannot be no in that user.

  • So to create an admin news, we're going to need to create it through the pipe and shell.

  • So we'll say Pontin managed a pie shell and here will say from users.

  • Top models Import user will say that a equals to a user.

  • We'll say that a dot use the name equals to admin.

  • A dark password equals two.

  • Let's say dude, 123 we'll say a dot is staff equals two.

  • True so that it's a staff member and ADA is super user equals, true as well.

  • And then just say a dot save and you see that it gives us the user's user.

  • That is, student cannot be no.

  • So we say a dot is student that said it equal to false.

  • And we say a dog is a teacher equals two True.

  • And now we can say a don't save and now it's correctly saving.

  • And if we were to say user objects dot all, then you can see yet a query set response with the user off admin, So we'll exit out of that now.

  • And let's call Pathan managed a pie run server so we can actually run the server and viewed in the browser.

  • This is what we have by default because we already have a bold directory appear in our project.

  • We have the Build directory, which is what's being referenced inside are based settings to use aesthetic files so we could actually come here to the log in and let's try and Logan, without user will say admin and pause in dude 123 And it seems that that didn't work.

  • Let's check the consul and we get a server responded with status off 400 bad request.

  • And if we take a look at the server here, it's not giving us any information.

  • It's just saying that the post to this euro wasn't successful.

  • It was a bad request.

  • And the reason for this is purely because we haven't set up rest or to understand our new custom user.

  • Because the custom users trying to see the default Django user that it's used to.

  • But we're not using the default use that we're using Island Custom User.

  • So we need to go into our base top.

  • I mean, we need to configure the wrist orthe serialize er's and the rest or register serialize er's, and you can check this in their documentation.

  • If you just sexual custom.

  • Django wrist orthe.

  • Then here.

  • The first link is a configuration for Jenga Restaurant Soup or 9.3.

  • So if we check that out, then here you can see it says you can define your custom.

  • Serialize is for each end point without overriding murals and views by adding rest or to serialize er's dictionary in your Django settings.

  • Possible key values are the logging serialize er that token serial Isa.

  • The user details serial Isa and all these.

  • So, for example, it says three rest or serialize is a dictionary where the Logan serialize er is a path to a custom Logan serialize er and the same thing for the token serializing.

  • And it also says, yet you can define your custom.

  • Serialize is for registration, however, note the custom of register serialize.

  • Her must define a define save method that returns a user model instance, and that's extremely important if we're gonna get this right.

  • So first, let's copy this default configuration.

  • They come back into base added there, and we don't need the token serial isa.

  • We just need the user details serialized.

  • That's basically to tell rest off that this is the user model that were using, and that is the specific serialize er for that model.

  • So we'll copy that.

  • User details serialize er.

  • Let's copy that pace that there and obviously the path will sort out in a second, and we can also specify the rest.

  • Orthe register serialize is which is also important because we're going to need to handle the kind of registration for our custom user meaning when the user's signs up.

  • They need to say whether their student or a teacher, which means that our registration process is going to be different as well.

  • So we'll open up addiction here and in here.

  • We need to specify the register serialize er so we'll add it there and just leave this blank for now.

  • And what we need to do is go back to our users AP and actually add a serial Isar inside it.

  • So we'll just say new file, which will be serialize er's don't pie.

  • How I got this to work is purely just by googling what is required.

  • And so this is primarily focusing on showing you how it comes to work.

  • But the model of the story is that when you don't understand something and you're trying to figure out what to do, google it and keep looking for examples of way.

  • Other people have done it and try to apply that to what you're doing Now.

  • The first serialized that we're going to create is the user serialize er, and this is the one that we've defined here for the user details serialize er.

  • So we're going to specify the path here to be users that serialize er's thought user serialize er and we'll take that name.

  • Come back into our serialize er's and we'll just say class user serialize er that inherits from the serialize er's.

  • And we need to import that.

  • So aside from rest, framework import serialize is and we're going to inherit the model serial izer.

  • And if we need to use that, we're going to need our model.

  • So we'll say from dot models import user.

  • And he will specify the class meta and say the model is a user, and then we'll need to specify the fields and the fields is just a list or fields on our model that we want to include in the cereal izer Now.

  • Normally, you would have things like the email.

  • You would have the user name, and in our case, we're going to also need to pause in the extra fields that we created.

  • So we'll add in parcel it as well, and we're going to add in our is a student and our is teacher and that's it.

  • That's our custom use of cereal, either.

  • That rest orthe now will use when serializing our user and now we need to handle the register serialize er, so we'll do the same kind of concept.

  • Well, say Kloss, custom register serialize er, just so that we don't have a really long name and this is going to inherit from the register serialize er, and we can see here in the register serialized class.

  • It's from rest or third registration dot views that register view and in restaurant registration serialize er's dot register serialize it Now you can either create your own custom serialize and handle it as well, or you can inherit from this rest register serialize er and do it that way.

  • So that's how I decided to do it.

  • So we're going to need to import that so we'll just come back in here and we've got a top and safe from rest orthe on.

  • We can actually remove that.

  • So we're saying from Bristol Registration serialize er's import the register serialize er and we'll install these course now that we have those installed, we've got our register serialize er, and we're going to inherit that in our custom register serialize er, and this is very similar to a model serialize her.

  • We can also specify a class meta and the fields.

  • So I'm going to do that as well.

  • We'll copy all of that right there.

  • However, I'm going to add two fields here as well.

  • So the 1st 1 will be the student and the 2nd 1 will be the teacher.

  • And this will just inherit from the serialize er's Boolean field.

  • And that will also be for the student.

  • And now that's actually jumped into the front end a little bit to handle that form.

  • So I'm actually going to close the models and we'll go into source to our containers and let's go to the sign up.

  • So here we have sign of genius and we've got a registration form, and basically what we want to do is just come all the way down here to the end of the form way.

  • We have the submit button and we want to add another form item inside here, which is basically going to be a select field with two options.

  • The first option will be student on the 2nd 1 will be teacher, so we'll add a form item and I'm actually just going to copy the get feel decorator and just paste it in there and inside here will want to add our select, so we'll just say, Select like that and we need to go to the top and import this from Auntie.

  • And we'll specify the get field decorator to be user type.

  • So that's how we're going to access it from the forms values.

  • And we'll say, Please select my user and we'll get rid of the validator here as well.

  • And inside the select, we need to add an option.

  • And inside they will be student, and the 2nd 1 will be teacher.

  • We'll set the value off the 1st 1 to be student and the value off the 2nd 1 to be teacher.

  • And then we can say that the place holder off the select is select a user type.

  • Now we need to import option as well.

  • So important option there.

  • And now we just need to make sure that we handle receiving the value off the option that's currently selected in the form.

  • So we'll go up to the top here and we'll say, Let is student equal to false initially and then we'll just grab the user type from the values because that's how we're doing it.

  • Currently, we have values of user name and email, etcetera.

  • So we'll say if values dot user type equals two student, then we'll say is student equals to truth.

  • And then here in the north, where we basically register, the user will add another field here which will be is student, and this will get passed into the on north dispatch method.

  • So if we go to the bottom here, we have ah North and we just need to make sure we passed that in as 1/5 argument.

  • So this will be his student and that gets passed into the fourth sign up, which is inside our actions.

  • And we'll add it as another argument there as well, just like that.

  • And now we just need to make sure that we handle that in the store.

  • So if you go to store actions orthe, then here If we scroll down to the fourth sign up, we need to make sure that we grab that arguments coming in, which is the is student like that.

  • And what I'm actually going to do is create a constant user and this use is going to have the user name the email, the password one possible to and it's going to have is student which is coming through as an argument there.

  • And I'm also going to set the is teacher to be the opposite off his student.

  • So that means the student is true.

  • Then teacher is false.

  • Then here, when we post to the registration euro weaken instead of passing this user that only has an email password.

  • One imposter too.

  • We're going to pass the entire object that we just created up here, which is the user object.

  • So we can delete all of that and just passin user as theon jek tw and what we're going to do is actually change the local storage handling so that, instead of setting the item of a token and an expiration date, were rather just going to set an entire user which will hold the token user name and all the details about that user.

  • So that way we can stall whether their student or a teacher as well.

  • So what I'm going to do is actually get rid of these local storage commands here.

  • But before we do that, we'll create another constant here, which will be our user.

  • And this is going to be the use object that we store in the local storage.

  • So it's going to have the token, which will be the response dot a key and just need to reference it with a colon.

  • Well, then also going to pass in the user name, which will be basically the user name that we passed in to the dispatch methods.

  • So we don't need to Parsa code on there.

  • Well, they're not going to pass in his student and will pass in his teacher as well.

  • And then we'll set the expiration date here to be a new date, just like how we created it over here and just use a colon as well.

  • And they we have our user so we can get rid of these command CIA.

  • And then we'll say, said to the item of user to be Jason dot string.

  • If I the user and you can get rid of the expiration that call there and instead of calling orthe success of a token will pass in a user instead and handle that in a second.

  • But basically, now we're storing this entire user in the local storage, which will come in handy later on as well.

  • And so let's go to the orthe success method here, which is all the way up top here, and we'll change it to receive a user instead of a token.

  • And then that user will pass in as the argument here, and it can remove that there.

  • And then we just need to handle that in the reducer, so we'll open up the reduces orthe.

  • We'll go to the orthe success, and we'll actually need to add some new state yah.

  • So, for example, the user name will now be Nola's.

  • Well, we'll have is student, which will be null and we'll have is teacher, which will be no as well.

  • And then we can come down here to the old success and and instead of this coming from action, that token, this will be action dot user Doc Token will take the user name, which will be action dot user dot Username will have is student, which will be action that user dot is student and the same kind of concept for his teacher, and we just need to make sure that in the action when calling or success, we make sure that, for example, here in the North check state method that when we call or success, we pass in a user and not a token.

  • So instead, up top here will say constant user equals to get item user.

  • And we're going to need to pass that source So Jason don't pass the local storage user, and that's because this is an object.

  • So we need to pass that into an object.

  • And then we'll say if the user is undefined or the user is no, then dispatch Log out otherwise will create an expiration date way instead of grabbing this from the local storage.

  • This will not come from user dot expiration date where users what we just grabbed over here, and we're saying, if the expression that is less than new date then log out.

  • Otherwise we will dispatch all success which will take in the user, and we'll just save that.

  • And if we go to the log out method as well, then instead of removing the expiration and token, we can just say remove user.

  • We can also open up the terminal to run the front end.

  • So let's just clear some of these terminals out here and we've got the package is installed.

  • So say in P M start, So we'll take a look here and it says Inactions orthe we have his teachers undefined and that we just need to set to the opposite Off is student.

  • And it says that the sign of Js doesn't contain an export named option.

  • So let's go to sign up.

  • And this is because our option inherits from the select, so we just need to say constant option equals to select dot option.

  • Now, if we check it out now, we can lock in its quick plug in and click on Sign Up and we have a username, email, password, password.

  • And if we click, select a user type.

  • And when we click the drop down here, we see student and teacher as the options for the user type on its inspectors here.

  • And that's what happens if we try sign up so we'll pass in the user name boss in an email and pause would and possibly a select used the type off.

  • It's a student, and if I click sign up, we see that gave us a era.

  • Connection refused, and let's take a look as to why that is and it says in serialize, is don't get the register serialize.

  • Er it got not enough values to unpack.

  • Expected to, but got one now This is because of a very silly error, which is that we didn't actually add a comma.

  • He had the end or and even pass in our path to the registers.

  • Serialize it.

  • So let's add this party A in our serialize is and this is users thought Serialize is dot custom register Syrian Leiser.

  • Just like that.

  • Now let's come back and try.

  • Le Guin will sign up brother again.

  • And if I click student and click sign up.

  • Now we get a 500 internal server era.

  • So let's go back and see.

  • And it says your integrity era not null constraint failed uses that user that is student.

  • So basically what this is telling us is that when the use is being created, it's not being passed in the is student and these teachers well, now the reason for that is because the default save method to actually save a user does not involve using the is student or the his teacher fields.

  • So what we need to do is override the save method.

  • So what I'm going to do is just define the save method here and we're going to say itself and request and all I'm going to do here is just, say, print the request so we actually see it come through.

  • And so with that, let's open up the terminal again and we'll go to the sign up page.

  • But let's actually get rid of the re routing.

  • Yes.

  • Oh, if we go to the handle, submit will not push ourselves to this year old.

  • So that way we can continuously test this.

  • And from this point here, overriding the safe method involves using an adapter which comes from Jang Go's ALOF.

  • So if we search your for adapter Django all north and we can just cook on this 1st 1 here, then here talks about the advance to usage off, creating custom user models and basically creating and populating user instances.

  • And here it says all that account adapted.

  • Our default accounted after that is what's used to create an instance of a user, and we can actually navigate to jangles rest orthe And if we go to the introduction, let's go to edit on get Hub and we'll just go to Jenga rest orthe.

  • And if we click on rest or and then we can click on registration and then serialized stockpile.

  • And here you can see it has an import from all off that account on adapter importante get adapter, and if you scroll down, you'll see the different types of serialize is.

  • So they've got the social account social log in, and if we keep going, we see we eventually come across the register serialize er, and you can see all of the fields on it.

  • You can see the user name the email password one and two, and then these validation methods the get clean daughter and the save method.

  • And here you can see it's saying adapter equals to get adapter.

  • And then it uses that adapter from Django, although to create a new user using the request, then uses the adapter to save the user by passing in the request and the user, and then it just add some extra custom stuff here for the custom sign up and setting up to use email.

  • So what I'm going to do is copy all of that.

  • The Save method, plus the defined get clean daughter and we'll come back in here, override the save method and we're going to need to import the adapter.

  • So let's go all the way to the top of the file and we'll say from although thought account adapter import the get adapter and we're basically going to use their logic, we're going to get the adapter.

  • We're then going to use that to create a new user with the request will assign the clean data to self by calling the get cleaned daughter.

  • And what that does is called the method on this class, which grabs thieve, validated daughter and grabs the user name and all these fields from that.

  • Then using the clean Datta.

  • It saves the user bypassing in that new user, and we can then get rid of the custom sign up and the set up use email and essentially, what we want to do is not only grab the user name password one and e mail will actually want to copy postured one.

  • So we have possible, too, that we can see as well and we actually also want to get to other fields which are the is student, and he is a teacher.

  • So now when we call get clean daughter, we're going to get everything that we need to create our own custom user within assigning it to self clean daughter.

  • And before we go ahead and save the user, we then need to just a sign.

  • The is student field and the is teacher field to our user.

  • So will say user Dot is student equals to self clean data is a student and do the same thing for his teacher.

  • And then at the end of that, we can call user dot save.

  • And this is very important this command your user dot save.

  • So now we then use the adapter to save the user and return that use at the end.

  • That's also very important.

  • Whenever you override.

  • To save method, you need to return an instance of whatever you're saving.

  • So we returned the user, and now let's actually see how this works out.

  • We'll open up the terminal and we see we get one area here, which is just the commas.

  • So let's add some Commons there, and now everything's working.

  • So if we come back to the boiler plate and this is actually on the local host.

  • Let's go to for 3000 and click sign up and look at that.

  • It was a successful poster quest, and we got a status of 21 which means that I use it was created.

  • And if you come back here, you can see that it's now saying Lockout, which means that our users actually logged in, and that means we can actually go and log in to our admin.

  • So if we go to admin, we're not going to be able to actually log in with our super user that we created earlier.

  • And so let's rather just go and use the user that we just created now and create them as a super user.

  • So we'll go back in here and actually had a new terminal, and we'll say, Pothen managed a pint shell.

  • Well, say from users.

  • Models import user.

  • Well say Matt equals to users.

  • Done objects don't get used.

  • Name equal to Matt on.

  • Let's just change that.

  • That's meant to be user.

  • And if we check what Matt looks like, there it is.

  • And if I say matt dot is super user equals true and matt dot is stuff equal true and then safe.

  • We can then exit.

  • And if we come back, let's refresh this and we consign in with Matt and there we go.

  • We're now logged in, and we can actually add our custom user into the admin.

  • So let's do that.

  • So we'll just go here to admin and will say, from dot models, Import user and then say Edmund outside thought, Register user and listen one too unregistered.

  • This groups here So we'll say from Jenga that contract at both the models import the group and then we'll say admin dot site dot unregistered group.

  • Now let's come back and refresh this.

  • And then we have our uses at the bottom, and if we cook on it, we have met.

  • And if we go all the way down, you can see that we have ah, his student and his teacher fields Way is T student is set to true and so that's actually created.

  • One more user here will log out.

  • And just to refresh this and say username equals to test test at Gmail and well said to use the time to be a teacher and if we cook, sign up, we're not locked in, Let's go here, go back to uses.

  • We have test scrolled way down and teachers said to truth, and that basically confirms that our sign up is correctly working.

  • We've got a custom user that is able to be successfully created on our front end and in the back end, and now we want to do is actually confirm that logging in works.

  • So let's log out here and we're here on the log in page and let's try and log in with Let's say, Matt, for example.

  • And if I click log in, then we get success as well.

  • So the last one we finished working on locking me in and creating our own custom user in the front end and customizing our serial Isar with Jang Go's wrist orthe package toe handle that in the back end, and then this one.

  • We're just going to finish off the user by adding interview said, to allow us to actually view all our users and also to view each user's profile and while we're at it will work on creating Theus assignment serialize er as well, which will allow us to create assignments.

  • So if you'd like to follow along with this tutorial, and you can just go to get hub and navigate to our teach me Django repositories.

  • So here it is.

  • Teach me Django.

  • And then you can just follow to these committee to see which commit you'd like to continue from will also add a description off these commits inside the project.

  • Read me file to help point out which commits where the starting code for each tutorial.

  • And so once you've got all the codes set up and you're ready to go, then let's get started, son.

  • Let's hit into the users app and we're going to go to the admin.

  • Now I want to work in the admin is because we're going to customize the way that the admin works in terms of these users and how they display everything on this form.

  • Now we can actually override this entire form.

  • We can change to be our own custom form, and that's what we're going to do.

  • So what we need to do is first import the user admin, which comes from the admin module.

  • So we'll say from Jenga contra dot admin import the user admin and going to say as the base user admin so that we can inherit from this and here will say cross user admin inherits from the base.

  • Use admin, and then we'll register that with our custom user.

  • And recently we posted a video on how to actually customize and improve your Django admin.

  • So I advise watching that video before actually continuing with this, because in that video we explain everything that we're about to do right now.

  • So instead, I'm actually just going to go through this rather quickly.

  • So we'll add the ad field sets.

  • And this is basically just a couple.

  • And the 1st 1 I'm going to say the name is none, and then we'll set up the fields to be email using them.

  • We'll add.

  • His student is teacher and we'll add the poss would one and we'll add possible, too.

  • And this is basically the fields that are going to display on the ad user form.

  • Well, then add the 2nd 1 here, which will be the permissions.

  • So that's the name of what we're adding and in the fields are going to be is super user and is stuff, and then we'll add the field sets and this is also going to be a list off topples.

  • I'm going to copy this 1st 1 here, However, instead of it being password one end to.

  • In this case, it's just password because now this is the display off the user once it's actually created.

  • And then we'll also add the permissions here.

  • And I'm also going to add some other options, such as the list display and the list of spares going to take in the email.

  • It's going to take in the user name it's going to take in his student and his teacher.

  • And then I'm also going to add the search fields, and this is a list of fields that weaken search by.

  • So I'll just add email and use the name.

  • And then we'll just say ordering equals to email.

  • And if we check the server, then we see we're getting this import era, and that's because this comes from orthe dot admin.

  • So now that's working, and if we come back in here and we refresh this page now, you can see it looks a little bit different because we're only showing the fields that we want to show.

  • And of course, you could leave it as the default view, but I think this looks a little bit cleaner and you could also go back to users here.

  • And you can see the list display is a lot nicer.

  • We've got his student and his teacher showing You gotta filter here.

  • You've got a search bar and let's add our ad mons email here.

  • We'll just say, for example, admin at gmail dot com.

  • And if we could add a user, then you can see all the fields that are required for adding a user, which is very convenient as well.

  • And so now let's just go ahead and create an A P I for our user model so that we can fetch users and that'll be useful so that we can come in here and add a profile link.

  • And then that would take you to, for example, slash profile slash one.

  • Actually see the profile of that user, and we're going to show him that profile Arthuis grated assignments.

  • So let's go here to the views and, well, first, import our user.

  • So you have to say from dot models, import user, and then we're also going to need our serialize is so we'll just say from dot serialize er's import, the user serialize er and we'll make this a view set so that it's not a lot of code.

  • So we'll say from wrist framework Import View sets.

  • And then we'll just create a clause use of you set that will inherit from the view sets model, view, set and all.

  • We need to do their specify the serialize her class, which is our users serialize er and specify the query sit, which will just be user objects.

  • Thought all.

  • And then we can take the use of you set and use that inside our own Urals.

  • DuPuy.

  • So we'll create one inside the user's model, so we'll create one inside the users f.

  • And so here we'll just say from rest framework dot routers import the default router.

  • And then we'll say from that views import our view set and I'll say our router equals to the default router.

  • And then we'll say router dot register the regular expression with an empty string like this.

  • And I'll say this is the user view set and we'll say the bass name equals two users and then said are your old patterns, which is what Django looks for equal to the route to Urals.

  • Then we can just go into our home directory into the Urals, up I and then in here we'll just add a part to the user's path.

  • So psychopath users and say include users thought Urals.

  • And now, if we also just make sure we add a comedy now we can see we're not getting any errors and we should be able to also check this out in our local host.

  • So if we go to slash users, then we can see we get the Bolton Jenga rest framework displaying the user list.

  • And if we went to, for example, users one and put a slash on the end of as well, then we get the instance of this user.

  • So now what we want to do is translate that into the equivalent display off a user's profile here in the front end.

  • And so let's go and close all of this art here and basically where we want to work is inside source and what we had started by adding and New Routier and this route is going to go to slash profile and then have an I D at the end of that, and we're going to create a component called profile to handle that.

  • And we'll just say, import profile from containers slash profile.

  • And then that means inside containers.

  • We need to create the profile.

  • Don't Jase, and we'll get started by creating a class called Profile, which extends from react.

  • And this time we'll use a pure component and we'll say Renda and then return some j six.

  • And we'll need to import react for this.

  • So say import react from react and that the end of this year will then create our map dispatched to props and map state to props, which will connect to the component.

  • So we'll say, import from react re ducks.

  • And this is connect and he will say constant map state to Props, which takes in the state and returns an object.

  • And, well, first, grab the token, which comes from ST dot author Token.

  • We'll grab the user name, which comes from ST dot orthe.

  • Don't use the name, and then we'll start the map dispatched to props.

  • It'll say map dispatch to props, which takes on a dispatch and returns an object.

  • And here we basically want to list out the dispatch methods to actually receive the user's grated assignments.

  • However, we don't have that functionality yet, so we'll just add a comment there and only work with this once we actually have it.

  • And then we'll just say Export default connect and will pass in the map, state to props and pass in the profile.

  • And if we take a look at this, we basically just need to fill in some content here in the return statement, soldiers additive and say hi and then just say this props using him.

  • And if we take a look at this, that's first log in and let's go to slash profile slash one.

  • And if we try slashed too, and we don't get the user name showing now, the reason why we're not actually getting the username showing is because our logging method did not save the user into the local storage.

  • We still need to configure that.

  • So let's head back here, and what we want to do is go to the store and to our actions off fourth and here with the orthe log in method, we basically just want to kind of do the same thing is what we did here.

  • We re created a user and then store that user in the local storage.

  • So just copy that and we'll do that right after we get a response.

  • Where the token is, the response started.

  • A key used name is the use name.

  • The is student is going to come from the daughters well, so it's a response.

  • Top data dot user type thought is student and then will pass.

  • The same thing for is teacher, and the expiration date is the same as well.

  • And then we just want to get rid of these Constance here and set the user to a Jason String of fire of the EU's object and then say orthe success off that user.

  • And so now if we go and try that again and we get a bad request you on the server, so let's see why that's happening.

  • If we go here to the path in 3.6, it just gives us a bad request.

  • It doesn't actually tell us anything about it.

  • And so basically, what we want to do is go back to our serialize er's and actually configure how we receive a token from the server.

  • So let's head back to the users app.

  • And if we go to serialize is now the reason for this custom serialize is so that when we log in, we receive not only the key from Jang arrest or meaning the token, but we also want to actually get the user type and that being either a student or teacher.

  • And we also want to get the user i d.

  • And the reason for that is so that we can store that idea in our user object and only navigate to our profile.

  • And so basically, what this means is that we're going to override the token serial izer that Jenga rest orthe uses.

  • So we can just say class token, serial izer, and again, you can find this in the documentation as we showed last time.

  • And this is going to just be a normal model serial izer, and I'm going to set the user type to be a serial Isar method field.

  • So serialize er, method field.

  • Now a serialized.

  • Her method field allows you to specify a method on the serial izer that will return the daughter that you're looking for.

  • So in our case, all we need to do is say, define, get and then underscore the name of the field you created.

  • So in our case, get user type and it's going to take himself and an object.

  • And I'll say that the serial Isar daughter equals two.

  • Now, in this case, this is going to be the user serialize er because we want to get information regarding the user and then return that information and that being the user type, so what?

  • We pass into it, we pass in the object on user.

  • So this is the instance that we pass into the serial izer and then we just say dot data.

  • So basically, we're getting the equivalent Jason object off that daughter and then we can just say is student equals two.

  • The serialize her daughter don't get is a student, and the same thing for is a teacher.

  • And then we just have to return a dictionary with the keys and values corresponding to what we want.

  • So in our case, we want Theis student to be a student.

  • Everyone is teacher to be is teacher.

  • So this get used.

  • A type is going to return this dictionary on our serialized and now all we need to do is just specify the fields off our token serial izer.

  • So we'll say Class meta and well said the model equals to a token which will import in a second.

  • And then we'll say that the fields are the key, the user, and then I'll use a type that we specified right there.

  • And so now we just need to go and import this token, which comes from Jang Go's wrist framework.

  • So I will say from rest framework, don't orthe token done.

  • Models import token and we can check the server and it's still running.

  • And now let's actually bring this to the left here and inside our orthe Gaius.

  • Well, just come here and say console dot log the response daughter, and we'll come back here and we'll log in and say, Log in with the same math, for example, and you can see that currently we're only getting the key.

  • But now we want to get all those extra fields.

  • So we just need to bring our token serial Isa and take this into our home sittings based up our and then here in our wrist or serialize Er's.

  • We're just going to add the token serial izer, and this is going to come from users.

  • Don't serialize Er's dark token Serialism And now let's try it again.

  • We'll go log in and you can see that currently the era was cannot read.

  • Property is student of undefined.

  • And that's because here in our oath, we're reading it from user type, which is something that's going to come back here as the user type field on the token serial izer.

  • So now let's go on log in with Matt, and now you can see that we get the key.

  • We get the user, which is the user, I D.

  • And we get the user type, which is specifying, Is student to be true and his teacher to be false?

  • And now you can see that we logged in as well.

  • And if I refresh the page, we're still locked in, which means that we are storing our object correctly in the local storage.

  • And now that's just going to add a link here, which will take us to our profile so we'll just come back here and we can close our serial Isar and based on Pie and we want to go into the layout so we'll go to containers layout and we already have connect imported, which will allow us to access thes map dispatch and map state to props from react re ducks.

  • And basically what we want to do is just add another breadcrumb item so we can actually remove the list item here, and we'll just make this profile and this is just going to take us to profiles and then an I D.

  • So well make this upper dynamically and you string substitution.

  • And this will be this stock props dot user i d Then the user i d.

  • We can just define in a constant map, state to props, which takes in the state and then just returns an object.

  • We will say the use i d equals two states dot orthe user i d.

  • And then that means that we need to store that inside r J s re ducks reducer.

  • So one we need to make sure that we get it on the Logan method and the sign up method.

  • So we'll come here and say that the user i d equals to the response to dr dot user.

  • Remember when we saw that when we logged out the user response in the console, and we'll just copy that and go down into the fourth sign up and also pass it here in this object users of that, in both instances we will grab the user i d.

  • And that means that inside our reducer, we'll need to pass in use i d.

  • As wth e action dot user user i d.

  • And in store this in the States as well, and we'll initialize it as no.

  • And now that means said, we just need to lock out and just to refresh this And if we look in with, let's say, Matt and if we kick on profile currently, it takes us two profiles slash undefined.

  • And so if we see why that is, we can close this reducer, and that's because we didn't put map state to props in our connect method like that.

  • So let's come back here and we'll just go back to

welcome to the start of a new tutorial, Siri's, and this is called Teach Me Jenga, which is a project built with Django and react, showing you how you can work with multiple users in a kind of mock online system where you can create assignments, filled them in and see the results of those assignments on your profile.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it