Django - Build a chat application without websockets (ajax)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
uh hello everybody this is joseph here and i know it's been a long while and today we are going to handle a basic topic in web development that is building chat applications now the go-to way to do this is to use web sockets so if you're using jungle you use something like jungle channels but it turns out many of us cannot really afford the luxury of owning vps servers and managing them and so we resort to using cpanel shared hosting which do not offer those capabilities so it is worth exploring things the old way using ajax to build our chart system so that is what we're going to handle today and right now i'm in my projects folder this is where i keep all my projects so i'm going to start with jungle admin start projects and jungle ajax chats so this is what i'm going to name my project and change directory into jungle ajax chat and well you can see the project is set up by jungle admin and i don't need to waste time let me just create my app so python manic dot pi start app and i'll name it chats now that is also created and i like to use it with a virtual environment it's actually advisable so if i turn the sdm and i will install all my sources that is jungle hgirf and the rest inside there well i'll be back when this installation is done so now the installation is done my virtual environment has been created uh i'll open this for uh vs code which is my text editor of choice now i need to go into this jungle ajax chats and i need to initialize my i need to put my app over here so that is loaded well so i just put in chats and i think that'll be it now go into my my url.file import include and then i'll include charge the urls then i need to go into chats and create a url file in order to avoid any errors sorry just my type into is not working because my vs code is still setting up oh it's done and i don't have junglish though so people jump sorry about this underscores i'll create my url patterns and they'll be relatively only one url sorry so a path where you'd specify the id of the user you want to chat with then we are going to have just one url pattern over here this is the only one we need next up we need to define how we receive messages and who are messages sender is and the rest so we're going to jump into our models and we need to get the user from jungle.com authentication importance user model and then i will say my user equals gets oh why is real school doing this to me sorry about that so my message which extends model that model is simply going to be a model filled with a sender which is a foreign key to user make the related name send messages and then we'll delete this model cascaded if there is a model installation deleted then we have a receiver which will be right about the same thing except the related name will be received messages and the one delete will stay the same and then we need an actual message i think i'll make it just a text field so yeah we can continue as many characters as we want now we need something to donate whether the message has been read by the user so by default you set it to false and we need a way to order them we want the last message to show up last in the chat room so for the ordering i'm just going to see created and oh i forgot to put this created here the time field go to now [Music] so that is all we need to define a message next up we need to create our view that saves these messages and this view wouldn't do much we just fetch the messages and we display them so that is what we are going to do but we are going to have two views and i think at first i said when you are about two urls for that matter so first we need to import login required to ensure that all people that access a particular url are logged in and then we need json response because you're using ajax and we need to send it in json format and then we'll from jungle shortcuts we have render we also need get objects of 404 what else do we need then from the models we also need the user model and then the message model then we also need we will do a little bit unusual query so we need a hue object we need json and i think that's all we need so let's go ahead and create our view we have a login required view create a chat room we take some requests then an integer to match the id of the user we want to chat with so we are going to get that user and we would send that user to get object of 404 user pk cos pk and then we are going to check for all the messages that the current user shares with this other user so you see the messages let's go to message the objects the filter now this is where our sort of advanced queries come in okay not yet my right now since the person is starting to know we want to show all the messages so we sent so we are just going to pass in all the messages the person share with this guy so we are going to see first of all cue objects so either the receiver is the other user and the the sender is the current user or the receiver is the current user we just request the user and then the sender is the other user now we have these messages we just need to render to a chatroom.html and we'll pass in the other user as other user and then the messages as messages but before we do this person we are going to update this query reset so that all those messages will mark as seen so messages.updates scene because sure now let's go ahead and create a template uh we created chatroom.html well i i must say that uh well this is uh vs cool shotgun for creating you know an html file for a basic standard html file so what we are going to do is we are going to have a header which will contain the username of the other user we are chatting with then we have a messages area which is going to contain all the messages people share the two people share so we say for message and messages and for then we are going to do a dev class of message class of message and then a little extra check here so we say if message the sender is going to request a user then we add a class of rights else we add a class of left and and then we also need something to delete the sender so message.sender then we also need a message content and that would be message dot message yeah i then oh i was just about to say we are done but i forgot we still need a way to input things so we have an input area and in it we are going to have an input with an id of message input with a type of text and then we have a button with an id of send button this is just sent we need to style this a bit because if i run it right now it will look very awkward so i'm just going to do some very basic styling not so much sorry so i'll reset everything box size and butter box then pattern of 0 0 i'll set the body to have a display of flex a height of 100 vertical height a background of a 66 dark you know the cool color then flex direction of column then i also need to style this header and i'll set a pattern of 10 pixels five percent five percent okay yeah i think it is then a background of four four color of actually eight so everything is dark you know i also need to style the messages area i'll set it to a height of 100 percent and then i need a minimum height of 70 vertical this really isn't necessary but let's just leave it uh in case it overflows you want the screw to appear then a pattern of maybe four persons and a background of you know it's also dark just with a little difference and i want the color to be 99 and pattern at the bottom to be maybe 10 pixels the input area i will set it to also have a display of flex and a flex direction of rule justify content center maybe i i needed to separate some of these to have utility first css because i see flex is repeating itself too much the message input i'll set pardon to 20 pixels wave of hundred percent and send button also has a pattern of 20 pixels 40 pixels hey in case this doesn't match you can change it uh any way you want it but in order to run this i need to create two user accounts so python manage.pi creates super user so the first account i'll create oh sorry so i already have a typo over here let me check it out so for ring and just before i run this creation for you so i need to make migrations and then i need to migrate oops that is a bunch of errors over here so from dirt import views i think that should do oh yeah that did the trick so recruits and we apply all our migrations sometimes when i think of migrations i ask myself how would i do if i had to write all sql by hand oh man so python money that price creates super user i'll create a user with the username of user i'll leave the email address password of password then another one which is user 2 and password again uh please use the secure password when deployed so python money.5 round server [Music] and then i can open over here to localhost 8000 uh and as soon as i do we should see this because we have no view 7 at this point but suppose you want to see a user buy an id uh we need to log in and we haven't setting any login routes so what we need to do is in order to log in you use the admin panel to login so for this user i'll do user password then i'll create a new incognito tab and do the same thing so that google browser tabs share different cookies so use uh now this one needs to be used to the alloy user password now for this one i can watch you i created you surface so you start to hear and then so that is how our chat room looks like and right now we don't really have any messages so well there's nothing to display in order to display something we need a way to create these messages and we are going to use ajax to do the creation and viewing of retrieval of messages so that is going to be our second view which is also going to be a login required the created view and we will name it hijacks load messages which are also taking requests then the id of the user the other user we get the other user goes get object of 404 and then we are going to fetch the messages again so messages is going to message the objects dot filter in this case we don't want to fetch messages that have been seen we want only messages that have been unread if now we are going to play the chat screen with all the same messages multiple times and then we would update these messages to show that they may seem and we will create a list where we are going to use uh less comprehension so what we need is the sender and the sender is going to be the message dot sender the user name we let me break this up we also need a message and that will be message message and then we need to know whether it was sent or received by the current users who sent is going to be just a boolean check so this and we say for message in messages yeah i play the arrow goes away and then what if the user is posting something so if the request method is a post then we need to get grab that message a person is posting so we say missing this equal to json node and we are loads because i think load reach from a file so but so we are going to do loads instead and we will move from request of body and when we have this message what we are going to do is you see you create a new message for it so the receiver will be the other user and the sender will be the current user then the message will be message then we are going to append uh this data just like we did for the other messages so we see sendai ghost request because we already know who the standard is then the message ruby m.message sent is going to be true and then when we come down here we are going to return a json response instead of render and we'll pass in this message list but we also need to pass and see if it calls false because if we don't do this if we don't pass in say if it goes false then uh jungle complain that it's only do json rendering for only a dictionary now if as long as we set this up all we need to do is some javascript to have things work on the front end so we add a style sorry not a style oh i think i undid something here okay some scripts and we have this this script yeah yeah i'm running out of my english don't worry okay so we just need to get so we get the send button then we get the message input message input and then we have a function we need to define a function to send a message and you grab the message from the message input so let's let's and once we have the message yeah we check in the message is just an empty string we return if it's not we set the value of this message input to and i'm just trying to like we are clearing it and then we do a fetch now over here we need to do i get the url so we are going to do let jumbo do that for us url will be from chatroom hijacks then other user user.id but because we are making a push request uh there are a few things we need to pass in if we don't then jungle for our own security sake so we set the method to post but the one jungle complain about is in this credentials block so we need uh sorry uh we our cross site request 4g yeah that one so those are going to be in the headers and the headers is also going to be content type it's going to be application slash json and i pronouncing this is a little hard for me don't worry and you get that from jungle when the page is rendered and then we get the body and we set it to jason dot the message let me format that properly put my comma there and where does the bracket end okay so we do a dot then because fetch returns a promise and then we say e.json another then again and [Music] this will give us a message and then you pass this message so what we are going to do is uh sorry messages so we say for message of messages then you do a constructs so this is a half of a helper function you're going to create and but before we do we also need a function to load messages and this is also going to do a similar fetch request except this time we are not going to use any post uh request and when we don't use any push request then we don't need to pass in any special csrf token or headers so we just do a simple fetch assistant gets and then dude then the which is taking in messages then the same for message of messages constructs message message let me do autoformatting over here so i'll bring this down and just i think that is better and we need to construct our message we should take in a message and what this is going to do is it's going to grab the message container maybe message area or let me just name message container so i'll use the query selector let me grab the class name i see this area i'm using query selector so that only one will be selected and please don't forget that the dots so that it doesn't return a list and when we have this we are going to create a variable class name which is going to be left and then i'm going to say if the message was sent then class name is right that was this already is left and then you create a diff and this is going to be a diff element and i'll add some classes to it the class is going to message and then uh class name so it's going to be either left or right and then i set the inner html notice i'm using backtext i'll set it to just a copy of what i have here here why is it uh this so i just replaced this with dollar sign and this one too with the dollar sign right here i'll be missing just send that and then i will say message is container dot append child and i'll see the screw so i think this is all but then i need to message send button dot add event listener so i'll listen to the click event and then i'll do send message so let's test that it works and then we can proceed to the next phase so i reload over here [Music] oh i forgot to add a url so i'll go to the views i'll copy the name of this function go to the urls or do path ajax and pk slash views dots and name because chatroom ajax i hope that is the right name i give to them let me see churchill ajax here so i reload here and let's see okay it filled because i did a typo church room sorry about that stop popping up so i'll pull this to the side to the left let me reduce the sizes a bit and i'll type hello and save just want to see that no error happened over here and we did a post request and let's open the shell then from chats the models import message so we do message the objects of all and let's say we have a message created so let's go over here also and then we create hello there that does not seem to work i'll reload and hello yep so the previous messages sent are showing just the new messages are not showing so i'll go into the terminal to try and see why oh this is def dot class list it's not a function so i just go into the construct messages so it's classless dot add okay a simple mistake but can cost us a lot unless you see the error is not showing how are you and we have how are you back here again um fine we have i'm fine hello there we have hello now i did not finish with a styling so it looks it all looks weird and i did that because i wanted to get quickly to working on so message or left so if we have a left textile line should be left and then you said the maximum wave to uh we set the color to a then message content so we have a background of h444 we have a pattern of 5 pixels 10 pixels we have a border radius of 10 pixels then we have a maximum wave of 80 percent and then we set the display to 9 blocks and then we have message dot right so the text align will be right and maybe i'll give that a different color so color what color be shootable maybe [Music] ccc perhaps so let me load and see if my styling is any good so yeah uh stalin works at least a bit and i'll test again how are you and yes it works the only thing is our messages are not loaded in real time so in order to enable that we have to set an event listener for this this uh load messages so i will say we set an interval should i say a timeout so an interval for load messages and i will set it to 1000 which means one second each so it means every second we are going to query to our reload again every second we are going to query to see if we have a new message coming in so i keep typing hello sorry how are you my messages don't seem to be loaded oh yeah so they are loading you can see them coming up here hello how are you so i'll intentionally delete everything message.object.org so now that everything is deleted when i refresh i expect to see blank pages and i can do hello there now let's wait to see if our message appears just past a second and our message did not appear so we need to investigate to see what was wrong one thing we can do is to one thing we can do is to unlock these messages so console.log i see this i reload i reload and it seems our messages are coming out as an empty list all the time so i'll go into my views and i'll see okay i have my message message.object.filter so yeah this this here is is a problem and the reason is our messages needs to be filtered from the particular user we are referencing so messages dot filter scene equals false and then you shorter with this query [Music] and now we can reload again reload again let's see if it works hello hi and still shoes off as an empty list so i would let me come back the default was false hey sorry my javascript is print messages then i'll print message list [Music] uh message objects underscore then i dot c so it seems whenever a message is created oh so i see uh one place now we might be causing an issue one place you might be causing an issue is we always mark a message a scene for everybody over here which really isn't what we want so what i'm going to do [Music] is i'm going to cut off the part where sorry sorry i'm going to cut all the parts this part and then i'm going to mark a scene and then i'm going to say messages equals messages or message of objects the filter so i mark a scene before i do this and then over here also over here also i check for those that are not seen and i am going to take this off and that is i am searching for the messages that we are the receiver of rush try again hello ah so record that day as soon as i mark the messages on scene it was sent so message look well let me reduce the time the time from a 100 second to cheap message of objects sorry gonna message.object.org dot updates scene equals false and the very moment i do this i expect to see those messages loaded up in the yep so beware oh so it was keeping my mind in in jungle a query set is evaluated only when you try to access a value in it like in the loop and at first i was doing messages.updates before i did this list comprehension so after the update this less confirmation results in having no messages at all in the query set so i had to move the messages that update from the top to the bottom so that uh the list comprehension is done before the updates is done and with that being done we can test it out i type hello user 2. okay for now i'll delete all the messages and then i reload each of the pages and they all start of blank hello user 2 now we get an empty list all around and we see the same message popped up for him around here takes almost about two seconds hello there you saw one yes nice to meet you nice to meet you too hey i i'm sure you don't want to spend all day listening to me chat with myself you know addressing myself actually so when i use it too so i hope this helps and next time you're working on the project and you are restricted by your hosting environment yeah you can use web success then you can just resort to this type and you can build your own chat system or you can very easily also use it to build some sort of notification system and i like see you again next time and don't forget to like and subscribe bye bye
Info
Channel: JOSEPH OTI BOATENG
Views: 4,160
Rating: 4.9740262 out of 5
Keywords: django, chat, ajax, without websocket, fetch, messaging, web, website, webapp
Id: EgR8TXDQRXk
Channel Id: undefined
Length: 55min 16sec (3316 seconds)
Published: Mon Dec 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.