Custom Analytics // Django Tutorial // Data Collection

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey YouTube it's Justin one of the questions that you might wonder is what happens with all of this data like people are coming to your site and they're probably looking at things and you want to start to better understand what they're looking at now you can use third-party tools such as Google Analytics but you're actually giving them a lot of this very rich data this data that you might use to transform your service or just want to keep it in-house and you don't want to necessarily give it to third parties you want to improve your service internally because data is becoming more and more important and more and more valuable to any business let alone any given website so the question is why then give it to something like Google or any other third-party service that does this that becomes a question that might go into the you know conversation you're having while building your web application and of course do what you need to do to make the best service possible so if that means giving some of your data way that's fine there's nothing wrong with that as long as your services and ultimately your users are benefiting from it but for us we want to see how we can manipulate or use this data to better understand our users and to make just a better service in general so that's what we're gonna be doing this one we're going to be creating custom analytics and an app specifically for that because it's actually fairly simple but we talked about concepts that you may have not seen before in the sense of using it this particular way so of course this is a part of a bigger section or this is a section part of a bigger course call the e-commerce that is still coming out all of that stuff is in the description below so check that out and please consider subscribing somewhere around here thanks so much let's jump into it when it comes to building web applications a lot of times you're gonna want to understand how your users use your web application to make it better now one of the ways to do this is to create your own app that will handle your analytics that's what we're gonna do in this one and I will say that if you go to the guide right here that guide will be a great reference for you in the future to implement in your own analytics whenever you need but what I'll also say is sometimes you might want to use a third-party analytic tools such as Google Analytics and you know there's absolutely nothing wrong with using those tools but the big key that I think is missing when using those tools is the control over all of the data right so even if you get all quote-unquote all of the data you still are giving a lot of control of it to Google or any other third party that you may be using so in our case we want to bring it and control it in our own project and therefore we want to create our own custom analytics and that's what this is all about is making sure that we're tracking and monitoring some of our user behavior to gain some key insights to make our service better that's the point is to make our service better and when it comes down to it at the end of the day you're gonna want to have some a little at least some analytics to make your service better and in our case we want to control those analytics so we will use custom analytics using Django but you also might implement something like Google Analytics because the time it would take to actually build everything that's in Google Analytics might outweigh the cost of it but at the very least we want some of our core things and then that way we might be like hey I want to improve upon what I've already got so definitely take a look at that guide you can probably go through that guide and get the majority of what's in this section but I will say that there will be some things that are left out of that guide on purpose so you actually see if you can even implement the things but we will do it in the video so even if you don't do it in the guide you we'll do it through this section so stay with us so let's move in to creating the app and crafting the model now of course we are doing this inside of our e-commerce add-ons right so the e-commerce course has an entire project that we build and that's where we're gonna be working in but what we're doing can be used in pretty much any if not all of your projects and the caveats we'll talk about when they come up so let's go ahead and jump into our project we see here and I'm gonna call my app of course analytics so let's go ahead and make sure our project is activated oops let's do it here okay and then we'll change into the source and then I'll just run Python Manish on py start app analytics okay so like in all videos we try to give you some extra context so we're not just going to be doing the model but we will also do you know put it in the admin and do some things there as well because we can give a lot more context and less time with a video so now that we've created the app let's go ahead and craft the model the very first model so we'll go ahead and import a few things here that you may not have used before or you have so the from contrib content types dot fields we're gonna import the generic foreign key field and from django contrib content types dot models we're gonna import the content type okay so I will explain what those things are in just a moment but let's go ahead and make the object first or the model first and we're gonna call it object viewed models model and actually I want to import the user model as well so we'll do from Django Kampf import settings and we'll say user equals to settings dot off user model and of course we're using this because that allows us to you set the user model whether it's a custom user or not that's kind of the point okay so we'll do the user and we're gonna set it to a foreign key of user and I'll even say blank equals to true and null equals to true now the reason for this of course is if my users not logged in I still want to capture if there's been some authentication so that probably means I want to put in an IP address right so I probably want to get that IP address so I'm not going to do that quite yet but I do want to add it eventually the next thing is content type and this is models dot foreign key content type again we'll explain that in just a moment object ID same thing models dot positive in this case it's positive integer field so it has to be a positive integer field it has to be a positive number and the point of both of these things is to really get the object so content type and object ID have to do with getting any object or any random model that we may have right so so in my case I have a product model but I also have like this model itself but I also have let's say a order model and a cart model and like an address model you know I'm all these different models and instead of declaring the model itself like each model or the instance itself so so in the case of the user this is like the actual user instance right so we actually set a specific user to this view if there is one of course whereas down here we set the model type or whatever the class is of that particular thing so I mean this could even be user right it could be any of them it's any of our models basically and then from here this is the object ID so the instance ID that's what this is gonna be so is gonna be user ID or product ID or order ID and what that does is allows us to call something called content object which then is our generic foreign key and that takes in content type as well as object ID so I can call this field then and actually get the instance so that I can get the product instance assuming that this one was set to a product and a product ID this gives me that product instance so this is like for like three literally three fields to do the same thing as one field so let's let's do the product example for a moment I'm not gonna actually save it this way so you don't have to copy what I'm doing and so if I did a product here and I stored a product with the ID of one so I have a product ID equaling to one that will link this object view to that one specific product and then there's a reverse relationship so on that product so let's say product object I can actually get object viewed set dot all so there's this sort of reverse relationship between the two from one direction I can get the product instance so the ID from the other direction from the product I can get the object viewed set and I can get the reverse this doesn't do it it's not as that it's not that convenient to do it but we actually don't need to worry about that too much what we are worrying about is the actual views we want to see the count and then possibly what type it is it's not even am completely important to have these three things you could use something like a URL so like let's say for instance if we just wanted to do a URL field we would put that in there and just get rid of all of the foreign keys I don't want to do that I want direct objects that I'm looking at so I can I can do all sorts of other things with it now the question is like why wouldn't I do product or you know then let's say for instance order like why wouldn't I just have a bunch of foreign keys in here for each each different model well you could do that way but then it starts to get very big of a model itself it starts to get complicated as well because if you create a new model or a new app with a new model you will have to remember oh I gotta update my object viewed I'd have to change this model to adjust to these new models with this I don't have to do that I don't have to change it at all and I don't have to worry about whether or not there's a URL to it I just have to worry about that there is a actual content type or you know the model name basically and I have to make sure that there's an instance and that's all I have to worry about so it's it's really a lot more flexible doing it this way although maybe a little bit harder to understand and hopefully hopefully that that cleared it up a little bit for you okay but even more will clear it up in just a moment so you can see that even in the admin itself so this is not all I want I'm gonna actually get rid of these comments I also want to get the timestamp so this is this is also fairly important because this is analytics right I definitely want to know when this stuff this happens when does view actually happens so we'll say Auto now ad equals to true so last thing is just bringing back in that IP address for now I'm gonna put it in as a char field there is an IP field but I want to have it in as a char field because of how different systems bring in different IP addresses I don't want basically I don't want to have to worry about the permissions and the validators on this IP address I don't want to have to worry about it at all so I'm just using a character field to handle it again there is an IP field just look it up on Django genius documentation but again I don't want to worry about any validators on here I just want it to work or not work and that's that's that okay so now I've got my object viewed item here there is of course going to be the STR method or the Unicode if you're on if you're on it if you're on a using Windows or it's just Scooby Python 2 and then you can return you know whatever sort of thing that you want here I'm just gonna say % s viewed % s as in some string substitution and just do self dot content object and self dot timestamp okay so that's just I mean you could you can definitely update like how that is a render but you know we'll just keep it like that and I'll do class meta this is also a little important for us in the future I'll show you why when we get there but we're gonna do timestamp and then I'm gonna just add a verbose name equaling to object viewed and verbose name plural oops plural there there we go object and viewed or objects viewed okay so the ordering being the reverse timestamp basically saying that it's gonna say most recent saved show up first that's all okay so we've got our model let's go ahead and add it into our settings module and we're gonna come in here right underneath addresses and put in analytics and we'll run our migrations now so python mini shop you why make migrations and python manage w-why migrate okay so let's add this model enter and min and take a look at it so go from the models import object view admin dot site register object viewed okay so let's run our server i'm gonna actually open up a new window here to make sure i have so I can basically so I can do more commands this is essentially it and run the server okay very good and let's go into the admin take a look we've got object viewed here obviously there should be none if I click on this now I can see the magic of content types see how I have all of these different models in here including the Django models right so I have my user model my address model my cart model my order model everything even the object view even this current model and then I can just put in an ID so let's let's just show you an example so if I did my hello a-team CFE user and that user looked at a product and the product ID was one and I hit save and add a none another I'll do the same thing and this time I'll do product ID of to hit save now it shows me oh well one of them actually exists so says t-shirt viewed on and the other one says none well why does it say none well if we look at our products we can see if there is a two so if I click on here and just change this ID to two yeah I don't have a product there so going back into object view let's change it to like four I hit save and now I have two products viewed here and that is actually the product instance that's why it's showing the name it's showing that string data that's coming from the product itself right so clicking on these products it's showing this that's we're back in the model that's what this is doing it's getting the actual object that we associated up here and it does it either gets that object or it returns none which is really nice it doesn't actually return an error which could potentially happen with foreign keys you you might get an error if you try to set something that doesn't actually exist right that hopefully that makes sense like if you're doing a foreign key and you're trying to set it to a user that doesn't exist there should be an issue and that has to do a lot with that reverse relationship stuff this doesn't have that same sort of reversal relationship so we now have an ability to save object viewed now we want to do a couple things prior actually implementing this one of them is how do we actually get this IP address now I think this is analytic data right hopefully you do too so we'll actually make that in the next one it's really really simple so it's gonna be quick so stay with us so when it comes to monitoring our user data a lot of times we want to get the IP address of our users this is more of a unique identifier to that user than anything now I will say that getting their IP address is sometimes a little tricky because of how your server might be set up so your server might be set up incorrectly or it might strip these headers for these IP addresses the other side of it is that users sometimes have ways of changing their IP addresses specifically so they're not tracked that's another part of this so we're not so concerned with getting this 100% accurate there's probably a way to improve this but it's something that I think works good enough for getting our IP address working here on a lot of servers at least on that port portion like we can't really control how our users do things but at least our IP address can control things to some degree okay so let's go ahead and create one I'm gonna go in my analytics app and I'm gonna make a utilities function in here or utilities module rather and it's really simple it's just going to be called to find get client IP client as in the requested users IP address and we're gonna do something like x-forwarded-for and it's request dot meta bucket and this is HTTP X underscore forward x-forwarded-for and then if this exists then we're gonna say IP equals to x-forwarded-for dot split comma comma and 0 this is just a method to grab that IP address otherwise we're gonna do IP equals to request dot meta get remote add and then we're gonna return that IP okay so again a very simple method on getting this it comes in from the actual request as you can see here if these headers aren't there yeah there's a chance that we might get not get the IP address either so there are several different ways on how this might have an issue so going back into our model we can now do something with getting this IP address like we can actually get it somehow before we can actually get it though I want to create the signals and custom view mix-ins to make it happen so we'll see what that means in just a moment stay with us if you've been working through this project with us you'll know about the concept of signals these are built-in methods that allow us to do stuff when other things happen so it's it's literally what it sounds like when something happens it sends out a signal and then we can create receivers all around our site to handle those signals now we use some of the built-in Jango ones like this pre save signal and then we make a receiver that will handle the data that is being sent through that signal so what we want to do is create our own custom signal something similar to pre save but for us it's going to be about the object being viewed so essentially it will be sent every time an object is viewed will send a signal instead of actually going off of the model so we're not going to create the model from the view right so like I'm not going to import this model in two different views instead what I'm going to do is import a signal that will be sent every time any sort of object is viewed on our site so to do this I'm going to go ahead and make a new module called signals and it's just it's really simple actually so we'll do from Jango dis batch import signal and then we'll just call it object viewed signal and it's gonna send signal with providing arguments equaling to a string and we're gonna do instance and request so any given object instance so like the product object with the title of t-shirt and an ID of one that is the instance we'll send through and then we'll also even send through the actual request that's happening hopefully if you watch the last one you understand why we might be sending that request in and a little hint it has something to do with the client IP so now that we've created this signal we can actually do all sorts of things to work with this signal so let's go ahead and it and I'm gonna go into my product views here so I have these detailed views I have a detailed view that actually has a get object method right so on here there's a method called get object and that's true with all sorts of places where there actually is an object now the ListView the product ListView is not the same right so we are doing literally when an object is viewed not when a page is viewed if it was when a page is viewed then you would just put it on every view or every page you would probably do something very similar to this and then just get the path or something like that but we're not doing that we're doing it when any particular object is viewed so in the case of a detail item being viewed or a detail slug being viewed this is where we're actually going to end up doing it so how do we go about it well I'm gonna I'm gonna show you one quick example of how you can just do it from here and that is importing this signal to our view we can go ahead and say from analytics dots signals import this object view signal and then scroll down to wherever that object being viewed would be so right here it's a product detail slug view I can actually bring in this signal and do send and the first thing is we have to add in a cinder now you are hopefully already familiar with this because in our signal for pre save we have a cinder we added our own arguments to be passed one of them was instance the other one was request so we're gonna be working towards something very similar to this but that very first thing we have to do in that view is have a cinder in this case our cinder is the actual instance so let's actually bring this down here where it's after our instance has been declared and assuming that there wasn't a 404 error we can do instance dot underscore underscore class so this is the actual cinder it's the sender of this view is the classes so this class will come through on with our signal in addition to the providing arguments that we named which was instance so we'll say instance equals two instance and request equals to request right so all of those things are set up and this will run just fine like you'll actually send out this signal and then we'll be able to map into this signal but this as you may see is can be a little bit redundant like I might have to rewrite this over and over again now if you're using function based views you will have to do this over and over again if you're using class-based views and more specifically class-based generic views much like this detail view here we can actually make something called a mixin that will handle this for us which is great so that's what we'll do now I'm gonna go ahead and comment this out and let's go ahead and make our own mixin now we want to create a custom view mix in specifically for class-based views so we don't have to be too redundant and also if something changes in our signal we only have to go to one place then well we'd have to go to two places we'd change it in the signal and then we would want to change it in the mix in that we're about to create so back into our analytics app we're gonna make a new file here and call it mixin spy and all we're gonna do is import from signals import the object viewed signal right so it's this signal right here we're bringing it into this object viewed signal and then we'll do class object view or object viewed mixin and it takes an object as an argument what we're gonna do here is define get context data it's gonna take in self args and keyword args we want to get the default context of whatever class this is going to be inheriting from what we'll see what this means once we put it in the actual view itself so the superclass self and then dot get context data args and keyword arts and I wanted to find the request equaling to self dot request and then I also want to get the object so the instance is equal to the context object and then I can just return context but inside of this return I'm going to send my signal so we'll do send and again it's instance dot class and instance equals to instance and then request equals to request now of course I also want to say let's let's instead of doing that we'll just get the object and then we'll say if instance then we'll run that actual call so basically if I accidentally put this mix in somewhere else it's not gonna run into any errors so if the instance or the object exists in the context then we'll run this now I'm gonna I'm just gonna copy and paste some code here and say show you that yeah you could do this other places right so if I did dispatch instead I could do something like this but the the problem that I think with this is as you're running this get object method again which given any given view we might have to actually we're like calling this all over again and we don't need to do that so instead I'm just gonna go off of the context data because we know for sure no matter what actual detail view it is it's going to get that object data and if it doesn't have an object then it's not going to run that signal so I'm gonna go ahead and delete this here and now we're going to bring this object viewed mix in into any given object view so let's go ahead and do that and now from instead of analytic signals we'll do mix-ins and then we'll just import this mixin I deleted that other one already and I'm gonna put this into every detail view that I see okay and detail view all right I should say every detail view that I see but also every detail view that I actually want to get the analytic data for it okay so now that I've got this going I have to move on to the next step which is actually handling the viewed signal so handling that in our model so there is possibility that things will break and if they do we will fix them when they break although the guide itself will not be broken it will be updated to account for any sort of changes that happen in the video but there is a good chance or not a good chance but there is a chance that some of these things might break because that's what happens with code that's why we test it that's why we go through it step by step as well all right so let's hook it in in just a moment so now it's time to handle the object viewed signal we have our mix in we have our signal we have now a way to actually work with this data so let's go ahead and jump into our model or analytic model here and we're gonna go and import the signal itself so we need to connect to it so we have to import it so from signals import the get or a sorry object viewed signal and then down here we're gonna create a receiver function for it so the first thing is to find get object or object viewed receiver and it's gonna take in sender well what are the other arguments that are being passed well those are these arguments right here instance and request so instance and request those are the arguments that are passed there are other things that might be passed by default so we're going to do args and keyword args to catch those things so now we should be able to see the actual sender we should be able to see the instance and we should be able to see the requests and also the requested user if there is one so that's how our receivers going to work so let's just connect it to our signal so signal connects and we put in our receiver notice I don't have to write out sender equals two here because I actually sent the sender along with the actual signal itself so let's try this out so hopefully now we're not gonna run into any errors but instead we're gonna print out this data when we actually look at something so let's go into our products into a product and what do you know I don't have errors but what I do have is three separate things I have a class of product I have a instance which in this case is t-shirts and then I get a request data information so what does that mean well first and foremost I can now create an object viewed item so I'll say new view obj equals to object it viewed that object create and we're going to do a few things first of all the user equals to the request that user that's fairly straightforward we've seen that before the next I want to get my IP address so let's go bring that in from the utility function here so from got utils and for utility method that is our module excuse me you know and then we'll go ahead and just say IP address equals to that of the request okay there's possibly a chance this will be none but let's just double check in our utility function here I'm gonna go ahead and say that if that's not there I'll just add none here just a little little improvement on that okay so now going back into our model we have two of the things done that we sort of expect what well how do we do the content-type itself right I can actually get the object ID that's fairly straightforward and that would be coming in here and saying object ID equals two instance ID but what about the content type how do I actually get a content type of any given class well this is actually fairly simple we say content type equals to content type class or let's call this C type as to not confuse the variable with the class itself so the four key we've already imported it and then we'll do the objects to get for model of the sender so the class that's coming through is that sender now of course that is the same thing as instance that class we've we've actually already seen that so that gives us the class that is coming through it gives us the same you know in the case of object viewed that it would give us that object feed class and this gives us that content type so we can actually set it down here for content type and then there you go that actually is how we create that actual object viewed so let's comment out these print statements here save it and let's go ahead and try it out I'll refresh in here a couple times I'll look at a few other products alright cool looked at a few things it's going to the admin let's look at our view to items and there you go we now have a way to store and save viewed items pretty easy and well definitely doable right hopefully like none of this was like really outside the realm of possibility for you the new things might have been the signal and possibly even getting the IP address but in my case this is how it worked and it worked just fine okay cool so the IP address is definitely something that you'll probably want to keep you don't want to actually publicly have it out there because you probably don't wanna give away the IP addresses of all of your users so if you're worried about security at all that might be something that you just completely scrape from this one of the advantages though and please let me know in the comments but one of the advantages of getting their IP address is you can actually parse that IP address and get their location without requesting it right so it's going off of their IP address so it's not perfectly accurate like a browser sort of request might be but it actually does do that so that's something else that's kind of cool about this and that might be something you put in your terms of use on your website that hey we get your client IP address when we when you use this site you probably need to put that on there but again those are legal things that I just don't know that much about okay so now I'm gonna stop for just a moment we will actually do this in the video but it's not in the guide and I won't leave you with a challenge so if I was you I would stop right now and try to actually get a user's session like how do you actually grab their session or more specifically their session ID and store it in such a way that's similar to what we did here like how would you go about doing that that's something we will absolutely do but again it's not the guide and I do encourage you to think through this now one hint I'll give you is there actually is a session model much like the content type or any models that we've created there is a session model for your users it's just a matter of how do you actually correlate those things there's a lot of it right in front of you right here with this object view so the challenge shouldn't be impossible to get but it is a challenge nonetheless so go ahead and try that out for those of you who are done with it or don't feel like doing it stay with us because we'll actually solve that in just a moment so now what we're gonna do is take everything we learned from the object viewed items to creating a user session model so it's very very similar to this but it's basically getting the session key for any given user and we can monitor what those sessions are going to be so that means that we have to create the model we have to make a signal and we have to hook these things in somehow so the first thing I'm going to do is actually import a couple things so we'll do from Django contrib dot sessions that models import session and I also this should be a capital S there I also am going to reorganize some stuff and then from Django DB models dot signals import pre save and post save okay so the next thing is I want to actually create or the first thing that I want to do is actually create a signal for my user logged in so in my case I have some login stuff so login view here but this is all my own custom login view you might be using a third-party package and there might be a good chance that they have a user logged in signal built into it but in our case we're gonna create our own user logged in signal so basically after the user logs in we want to have some sort of signal so we can connect to it now this is great for our user session but it's also great for other things that you may want to use that information for so in our accounts app we're gonna go in here and do signals dot pi and I'm gonna copy everything that I've already done and I'm gonna call this user logged in and really all it takes in is the request so it's gonna take in the request and probably even the like user itself like so after the user logs in it's probably going to also take in that as the sender so the actual user class that is and then other than that it's just the request okay so where would we put this I'm gonna go into my view for login and just put it in here so after I login so from dot signals import user logged in signal and literally after this or before that redirect I'm just going to do user logged in dot send and the sender in my case will be user dot class and then the actual request is going to be what's sent in you know we might as well send in the actual user itself so we'll say instance equals to user so the actual user instance very very similar to what we've already done so that means I just need to change my signal a little bit and say instance here okay so we've got a logged in signal going and it will absolutely run so that means back in my analytics I can now start to create something with that so before I do I'm going to go ahead and import from accounts dot signals import user logged in signal and then we'll scroll down here and I'm gonna do define user logged in receiver and the sender instance request args keyword args okay so the users logged in I can do something with this user being logged in and we'll go ahead and see what that is and maybe just a moment so I'll just say print out the instance or the user and then we'll just do user logged in connect and there we go okay so now we need to actually create our model for any given user session so we'll do class and I'll say user session and it's going to be models that model the reason I'm not calling it session itself has to do with this right here we we don't want to call it session because the built-in Django model is called session so I'll leave it in as this and then I'm gonna virtually copy the object view the reason I said that it's similar because it's almost identical with it with the exception of a couple things and that is these right here I don't actually need those things instead what I need is just the session key and we'll do models dot char field max length I think we're good if we do a hundred we're probably good beyond that too or a little bit less than that I think I think you need to have a minimum of 50 I think that's right you can look up the documentation for that one and then we need two more things here so we've got a user we can do an IP address again and we can get a session key and stuff like that so the reason we would do the IP address is to to track the data between the user session IP address and then an object viewed and if it's the same user there might be some conflicts or some things that we want to implement to prevent those things from happening so there's a couple things that I do want to have in here one of them being active and will say models dot boolean field and default being true so whether or not this is an active session should we keep it active or not oops there's that idea and then we want to say if it's ended so this is more referring to if we manually end this session I'll give a default of false and then we're going to do our STR method if we wanted to I'll just leave it like this okay and then now that we've got this I can actually create this so let's go ahead and do our make migrations Python manage up to I make migrations you look looks like keyword argument is repeated oops that's this so we need this to be blank try that again contrib dot sessions oops there we go so that's the import right there make migrations there we go and then python managed to py migrate of course we haven't used that session model just yet because we're actually going to be storing the key much like we stored the object ID up here we're just gonna be storing the key down here okay so after the user logs in we now want to create one of these user sessions so this is where we will actually get the session ID with every request we can say session key equals to request dot session dot session key this is true as of jenga 1.11 it might change the location but that is true and that should be true for a while actually and again we can get the IP address from that request much like we did here okay and then the user is the instance all right so who's being passed okay and now we just create a new session so user session that objects dot create and what are we create we say user equals to user the IP address equals to the IP address the session key equals to the session key and of course the left-hand side of this are the keyword arguments of the arguments also known as these things the right-hand side of the variables inside of this method here so that creates our actual session and it will store it in to the database so the before we actually like finish this off though is I want to make sure that I can end sessions that is remove them altogether so to do this we have to create some sort of method that will actually go about ending these sessions before I do that I will bring this into my adult analytics though admin or sorry the not into the analytics but the admin okay so we now have our session here and let's go ahead and take a look let's log out log in and we have to log in with our new one okay let's go into the admin user sessions I get a session object notice my IP address is incorrect but it gives me a session key which is nice so how do I actually end that session well let's just do it in the shell real quick so Python managed to py shell and I'll say session key equals to that string and then I'll do the imports or or all of our this session model import that is and just do session objects that get and this is going to be we want to get the actual key itself which is coming off of the primary key so this is the session primary key and we have that object and then if I just do dot delete and refresh here what do you know I have to login again so that is how I can go about managing and deleting these sessions and which is really cool so that means in here I can say define and end session take itself and really I'm just going to grab that session key again so session key equals to self dot session key and then we'll just go ahead and do try session dot objects that get PK or a primary key is equal to this session key and then we'll do dot delete and let's say ended equals to false and then if it works there will say ended equals to true or rather will say n it equals do self dot ended and now we'll say self dot ended inside of this try block self attended equals to true and self dot save and then we'll return self dot ended and also we might want to put self dot active being false okay really simple way to end that session but what I want to do also is if I change this from being active I want to just run that in session portion and I might also want to have a way that if this is created that I delete any of my other sessions so I only have one session like actually in use now the requirement of one session is probably not as big of a deal for something like e-commerce but it might be a big deal for other sorts of things so to do this it's we're gonna create our receiver function so I'll just say the post save receiver and it's gonna take in sender instance args and keyword args actually we won't also want created in here so we'll say if created then I want to get all my other user sessions so I'll say Q s equals to user session dot objects that filter and we'll say instance or it sorry filter by user equals to instance user and then we're just going to exclude pkeq or well ID equals to instance thought ID and then for I and Q s I dot end session and that's it so that's same one right so like every other session that might be in there as soon as they're logged in it's going to go ahead and end that session for us really simple then finally we just do post saved connect and this receiver well let's call post save session receiver sender equals to user session okay so we will try this out now I'm gonna go ahead and log in with my session here I log in oh nope that's actually not where I want to log in the Django admin it won't work on that I think there might be a signal somewhere for that but we want to log in to our main site where we actually call that signal run that okay great now let's go into an incognito window and try it again and I'll do hello at team CFE the password login and then I'll refresh here yes I'm out I'm gone cool so I'm not going to do it but the less challenge would be how do I have multiple sessions like let's say for instance I have a max session how do you how do you go about doing that it's actually very similar to this I will say one more thing is with this this filter you might want to say ended equals to end it equals to false and active equals to false just to make sure we're not always going through everything that is related to this users session that that's probably a little key thing there but in general how do we go further how do we say oh I want to allow them to have let's say five sessions and anything beyond five how do I update this receiver function to handle that but that's it that's that's handling user sessions and even forcing log outs there there might be one thing to that you would want to do in this let's say for instance a pre save and we'll do pre save session receiver and it's gonna take in sender and instance or well actually we won't do the pre save we'll leave it in as a post save and basically we want to say if instant or if not instance active and not instance that ended then I'll just do instance that end session so this won't create a loop because we end the session here and basically saying if this is true then this is not this this won't work or sorry yeah if not false so this would be false and if this is false so if this if this is false and this is false then we'll end the session but one of these will be true so there's sort of the opposites of each other right no matter where we set them they are the opposites of each other and then we would go ahead and in session so that means that in the admin I can also end that session as well which let's go ahead and try that out I'm gonna login to the admin and I'm gonna log in as this user so if I look back here I'm still logged in right because I logged into the admin and that signal wasn't called so I can go into that session and hit active hit save session object changed successfully refresh in here they're gone and of course from there you can then deactivate the user and do all sorts of stuff with that like you could even go even further and say oh I want to have a post save user this is going way too far but let's just let's just do it real quick and I'll say post save user posts a user changed receiver and we'll do define that this I think is actually also fairly important so we say send our instance created and then args keyword args and we'll say if not created so this user was not created just now what I want to do is say if instance dot is active equals to false then I want to get all of my query set items here and in their sessions so all of them that are not ended basically let's let's end all of those sessions because I just said hey this this user is no longer active and then that means that all of their sessions should end immediately this is just like a nice failsafe that you might end up wanting to implement I'm not gonna implement it because I actually don't need that here it's much more about learning and understanding this stuff and further I'm also not gonna end implement this one either I don't actually need to end anyone's session but I will leave that code in there for you so actually let's let's do it something more like this and I'll go in my configuration and say force session to one equally to get attribute of the settings module to for session to one and we'll say false then come down here and say if for session to one then you'll actually connect to that stuff and then we'll do that same thing again and force user end session inactive or force inactive user in session again imma leave it as false and put that down here as well so if that so basically what this is doing is looking in the settings module for these two things and then the default if it's not there it will just default to false so again I can just copy these and go into my settings module here and post in these things and just really say false on both of them and leave it as false but just allowing you to have just a little bit better understanding of how you might go about doing these things and using it in your model so that's it for monitoring user sessions I realize this one was a little bit longer but we really brought a lot of things together here in our quest for better analytics so the last challenge that I'll leave you with that I'm actually definitely not going to do at least not now is how do we change our object viewed to just page views like how do we analyze or do analytics for any given page view so go ahead and try that out if you have any questions on this user session stuff please let us know I really actually was so stoked when I found out about how easy it is to do this stuff and hopefully you are - hey thanks so much for watching I build everything that I can to help you guys launch your projects faster better and more often so please consider subscribing join CFE dot-com /youtube is a quick way to our youtube channel join CFE comm slash projects and just join CFE comm that is where all of our stuff is and I really hope that you join us there as well thanks again so much and I can't wait to see you in the next video [Music]
Info
Channel: CodingEntrepreneurs
Views: 24,744
Rating: 4.9658847 out of 5
Keywords: djangourlshortcfe2017, django 1.11 tutorial, django tutorial, install django on mac, install django with pip, install django with virtualenv, virtualenv, python django, Django Web Framework (Software), Mac OS (Operating System), Python (Software), web application development, learn django, installing django on mac, pip, python package, django, kickstarter funded, beginners tutorial, trydjango2017
Id: SMRaHSZiwWE
Channel Id: undefined
Length: 57min 54sec (3474 seconds)
Published: Tue Oct 10 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.