How to build a simple Twitter clone using Django and Vue.js - Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi and welcome to how to build a simple twitter clone using django and vue.js the project we will be building during this tutorial will be called oink oink and it will contain much of the basic functionality from twitter and other social networks like user profiles following other users a feed with posts likes and the possibility to send each other direct messages i think this will be a really cool project to build by the end of this video you have a social network looking like this you can sign up and you can log in if you log in with the user you will have a feed with oinks from yourself and the oinker you are following you can also like the oinks and you can follow other oinkers you also have possibilities and the message as you can see here we have a conversation if i send you to code with stein log out log in again with code with stein i should get a notification up here admin send to your message so everything here works perfect i hope this looks interesting and that you want to follow along feel free to leave a comment below if you have any questions the toast i'm going to go through in this video is setting up and creating a project create folders and structure and similar create app for the core views create app for the oinks and app for user profiles then i'm going to create a base html files create a front page with some information page for the login and sign up on to create a page for my feed make it possible to sign out make it possible to write knowing this is going to be submitted to the backend using vue.js going to make it possible to search for oinkers and oinks let's make it possible to follow an anchor going to make it possible to see my followers and who i follow i want to make it possible to see other oinkers followers and who they follow what megabus will do like an i want to add direct messages so you can see a message and have a list of all your conversations and this is going to be some kind of vue.js then when i finished i'm going to deploy the project to a live server i will begin by creating a virtual environment for the project i always recommend that you do this this way the deployment will be much easier because you can have the exact same python environment on both places and it's and it's much easier to maintain i create one by saying virtual env and then the name which will be oink oink three 364 four is the python version i'm running on my computer and then i can hit enter next i want to go into it by saying cd oink oink and then i want to activate it by saying source bin activate you can see here that it's prefixed with the environment i mean every time i run pip now it will install the packages just for this environment so the first package i want to install is django pip install django this will automatically install the newest version of django which currently is 3.1 and also install a copper of other dependencies that django has now that django is installed we can easily start a new project by running django admin start project link link and i can also go into this cd on going like that here's a couple of standard files from django i will come back to all of these later and explain what they all do don't need to be any more overwhelming than it already is before i do anymore i just want to initialize the database i do this by running python manage.pi make migrations i don't have any migrations yet but i always like to run this command first then python manage.pi migrate this will run the actual migration so now i should have a simple sq library database here in the root as well we can test that everything is working by running a development server python managed by run server django comes with the default web server for development but this is not suitable for production so the install worked successfully perfect so i can also go back to the command line and create the super user for the django admin interface python manager pi create super user then i just say admin admin at oinkpoint.com and then a password oops yes so now i have a super user so i can run the server again just to log into the admin interface like that sign in with the user i just created here you can see that we can access the users there's only one for now the groups and similar this comes automatically when you install django later in this video you will see posts there and all of the other things from the database so you could also add new users here and similar if you wanted to do that but right now everything is working and we can continue to create the structure for the project but before i continue i want to say thank you to my first patron frederick rowland thank you so much for the support if anyone else wants to become a patron for code it's time i will add a link in the description below so here i want to just stop the server again and create a new folder in the root mk there apps this is where i want all of the apps to be located i like to organize all the django apps inside this this apps folder because this gives a very clean structure without too much mess in the roots folder i can also start the first django app but i want to create a folder for this core and then i create a new django apparent python manage dot pi start app another name and the location which is apps slash core then i can create actually i can go ahead and open the project in visual studio code so i can just run the server so i have it running and then i can go to visual studio code so to the left you can see the project structure apps and then the other files that came earlier inside the core apps folder i want to create a new folder to place all the templates so inside there is templates and inside the template folder i want to create one called core this makes it easy to to find all the files later and then the next thing i want to do is to register this app with django because django doesn't know that it exists yet so inside the settings.pi file there's a list called installed apps at the bottom here i want to say apps dot core and then i can save also i can go to the next thing i want to do is to create the base template for the whole project so inside the core folder here i create a new file called paste.html and then i start adding the html here add a doctype html head and some metadata here meta chore set utf 8 letter name viewport so we can make this mobile friendly as well content width device width initial scale is one you can also set the title for a page point point and i want to include a css framework called bulma because then i don't have to think too much about the styling for this project link corral style hrf https i will add a link to this in the description below cdn.js deliver deliver.net npm boomer at 0.90 css bulma dot css min dot css because we want the minified version okay below here i want the body on top of the body i want a navigation bar knob class nav bar and i want this to be blue so i just use a gloss from bulma is info roll navigation i want the logo placed to the right i placed this in a class called nav bar navbar brand and then i need to add the link to the front page plus nav bar item because if i add this and bulma will place it in the middle in the middle of the navbar strong oink oink like that next to this i want the hamburger menu to be showing on mobile devices a class navbar burger span area hidden equals true and i want three of this like that so that's the enough bar for now we'll go back to this later just like to add some comments so i can separate the code then i want the content section clause content copy this and content in here i want to add something called a block this is django's template language block content and then i close it by saying end block this makes it possible to extend this base template so i will show you how it works in a second when i create the front page template front page html so here i say on the top extends core slash base dot html and all i have to do in here is a block content and block in one word div class container div class columns div class column is 12 h1 plus title welcome to oink oink and save so this code will be put in here automatically when django renders this page to test this i want to create a view so we can see that everything is working so in the course core folder we have a file called views.pi here i can say def front page request and here i just want to render the html for the front page so i say return render pass in the request parameter core front page.html to test this view we also need to import it to a file called urls.pi urls is kind of a collection of all the available content for the project almost like a table of contents so if i scroll down into the oink oink folder i have a file called urls.pi here i can import the front page view we just created from apps dot core that you use which is this file import front page then i can add it to the url patterns pot the front page shouldn't have anything in here because it's just the oink oink.com then i pass in the view and give it a name so i can reference it from other places okay like that so if i save now i can go back here everything seems to be working and i can go to the browser to test this if i refresh now you will see this and everything here is working it's perfect as you can see we see the title this comes from the front page.html and the rest here is from the base.html this is because we are extending this file and just passing data into the blocks the front page will contain a little bit more information about the social network and similar but this is something i will come back to i see that i managed to say content here but this should say close section refresh so now we get a little bit space over here too okay i can create two more templates file one for the login and one for the sign up i want both of them inside the same folder here login.html i want this to extend the base template as well core slash based.html the reason why django can find the core folder in this templates file is because if i go to settings.pi under templates and it has that update to true this is default so it knows to look for a templates folder inside all of the apps so inside the templates folder it finds core and inside there the file called base.html so i also want the block content here as well div class container div clause columns div class column is 12 h1 clause title log in then i can end the block and save and i can just copy this create one more file sign up dot html paste it sign up before i do anything more there i want to create the user profile models these will be used to extend django's default user model begin by creating a new folder and django app i do this in the command line mk there apps slash winker profile instead of user profile and then i start the app python manage.pi start app winker profile which is the name of the app and then the location hit enter and then we can just run the server again and i can go back to settings.pi and just register it up here before i forget it apps dot oinker profile save and then i want to change the database model for the oinker profile so i go into the unker profile folder and open up models.pi first i want to import the user model from django from django.com trip dot auth dot models import user below here i want to create my model class oinker profile models dot model i want one field to reference the user this is models dot one two one field user on delete models dot cascade so when i delete the user i also delete the oinker profile i also want one field called follows models.many to many fields i want this to reference itself related related name is followed followed by this way i can get the follows and i can also get followed by so it's very easy to get to check who a user follows and who is followed by i also need to set symmetry call to false sorry symmetrical equals false i do this because this means that if i follow you you don't automatically follow me back below here i want to say user.oinkerpro sorry lowercase linker profile equals property lambda u colon winker profile dot objects dot get or create user equals u and they get the first one the lambda function makes it possible to just create the user object when i sign up by user and when i want to reference the oinker profile it tries to get one and if there aren't one it's going to create one so when i sign up i don't have to create an oinker profile also so now we can save and go back to the command line and just update the database python manage.pi make migrations so here it says that i want to create a new model called oinker profile and then i run the actual migration by saying python manage that by migrate so now i can run the server again i also want to do one more thing inside admin.pi and that is to register this model with the database with python so i have it in the django admin interface i can import it here by saying from dot models import oinker profile admin.site.register anchor profile and save you can just close this for now and now that we have set up everything we need for the oinker profiles we can make it possible to sign up and log in i will begin with the signing up functionality so inside the views pi in the core folder i want to create a new view here def sign up just pause in the request i want to check if the request method is post so i say if request dot method equals post if it is i want to get the data from the post user creation form this is a class from django i will import it in two seconds just pause in the request post data so to use this i'm going to import it at the top here from django.contrib dot forms import user creation form so django will handle a lot of things there in the backend for us and then i want to check if the form is valid if form that is valid then i can create a new user by running form dot save when the user is saved i want to log him in by just pausing a request and then the user this is also a function i need to import from here so i just copy this import login and save so now if the form is valid i will create a user and log him in and then i want to redirect the user to the front page return redirect just pass in front page like that so this is also the last thing i need to import i can just copy redirect and pause paste it behind shortcuts because it is a shortcut from django if the request isn't post i want to just show the form so then i say form equals user creation form and just empty like that and then i return render request course let's sign up dot html create a dictionary form and pause in the form and save with the viewer ready now we can change the signup.html to show the form so if i go back to signup.html below here i say form method post action sorry action i can just put a dot and then i need to add in a csrf token this is something from django to make it possible to not get a post request from other places so it's a security feature then i just say form dot s p which is for paragraph and a button to sign up button clause button is success type submit sign up and close it so then the last thing i need to do is to go back to the urls.pi file which is located here and import sign up then i can copy this whole path say sign up sign up sign up and sign up so if i go to slash sign up now i will go to this view but i want a button in the menu to go here so if i just go back to the base dot html inside here auto creative class nav bar menu i want this to be located to the right on the screen so therefore i use clause called nav bar and and then i say div clause nav bar item div clause buttons because i want two of them h raf url sign up so url is a function from django which takes a parameter sign up which is this one the name so when i call the url it automatically get this from there and paste it in here for me in case i change it or something like that plus button is success because i want it to be green i want to have a bold font sign up and on the next line i want a button to the login i don't have any urls for that yet but i can create a button is light log in and save so now we can test this to create a new profile if i refresh now i can go to login now i can go to the sign up and i have the default django's sign up view so i can create a new user code with stein and then the password sign up and i was redirected to the front page this should mean that everything is working okay then i just want to do a change in the menu so we can test if we are actually authenticated so if i go back to base.html here and inside these buttons i can say if request dot user that is authenticated and if i'm not i want to show these two buttons just close the end if and here i want to say h raf url log out i will create this in a couple of seconds clause button is danger log out and save if i refresh now i will get an error because i haven't created the logout view yet i can do this inside the urls.pi on top here i can just say from django.comtrib.org import views and below the sign up as a path log out and here i want to use a view from this views so i say views dot logout view s view name logout so this is a default view from django that lets me log out the user so we can go ahead and try this if i click there now i will be redirected to the admin interface logout page but this can be changed so if i go back to the settings.pi by the way settings.pi is globally settings for the whole project up here i can say logout redirect url front page so when someone logs out you will be redirected to the front page if i want to test this again i need to include or implement the login view so i can go to the login.html and show a login form here form method post action like that post in sorry csrf token again form as paragraph and then a button class button is success type submit log in i don't need to create a view for this because i can just use django's default login view so if i go back to urls.pi again i can here i can say path login views dot login view dot s view name login and there's a couple of more things i need to do i can go to settings.pi and set login url so if i try to go to a page where i don't have access it will be redirected here login which is this name next i just need to go back to base.html to set the url here so href url pass in the name of the view like that so if i now go to the front page again click login okay sorry i forgot to set the template name in the urls file so here i should say template name core slash login.html and save refresh and now i see a default login view okay so now i can log in with code with stein which was the user i created log in the page i was redirected to now doesn't exist yet i want to change the default page to be redirected to something else but to do this i need to create a new django app so i'm going to create a new app called feed i'll begin with creating the folder apps feed and then i create the app python manage.pi start app feed this is located here so then i can run the server again and go to the settings plus pi file to register this apps dot feed and save and then i will continue by going up here finding the folder creating a new view inside feed slash view def feed request colon return render request feed slash feed html i will create this soon but this is a page that that requires login and to do this i want to use a decorator called login required i need to import this from django as well from django.comtrib.org.decorators import login required so this is just an empty view for now but i will add more hair later what i want to do now is make this the default page you are redirected to when you are signing in so here i say login redirect url feed and then i need to import this view to the urls section from apps dot feed dot views import feed and i can add this below here i want to separate it a little bit from this part feed feed and the name is also feed like that and then i just want to create an empty or a very simple template so we can test this so i'll create a new folder templates because django will look for it and then a new folder feed and inside there i create a new file feed.html this i also want to extend the base core based.html create a blog content and i want to div here container div plus columns if clause column is 12 h1 plus title my feed and save so now you can test this i just want to add a link in the menu for this so if i go back to base.html i can copy this because i want it outside here and if and then i create a new link href url feed this also need a clause nav bar item feed and save so now so just want to go and test this okay something is wrong chango contrib with the decorator okay this should probably be decorators in plural refresh and now we can click feed and i will be sent to my feed if i log out i will be sent to the front page and if i log in again i'm sent to my feed that's perfect the next step now would be to make it possible to add posts or oinks as i will call them in this project i will use the feed up for the oink database model so if i go into feed and models.pi file i can create them here i want to import the user model from django.contrib.org.model import user and then i create a new clause called poinc passing models dot model and here i want the body to be the the link itself the text models dot chart field max length i want to adjust that to 255. i want to create that by field model.foreign key this is the user related name links so i can get them adjusting user dot links on delete equals models dot cascade so when i delete user i also delete its points created at should be a date time field and i want this to be filled out automatically to adjust the auto now add equals true i want to add a meta field here this is options for the model i just do this for the ordering ordering equals create a tuple minus created at so the newest one is always at the top and then a comma here since this is a tuple so i can save this and just go back to the command line to update the database again make migrations python manager pi migrate so now i created the model oink so i can run the server again go back here and into admin.pi and i want to import this model to django admin interface from dot models import link admin that site to the register oink so now i can go into the admin site to check this out refresh okay just have to log in again that's the wrong password there so here i have the anchor profiles and the oinks there are no yet but we will be adding them in the front and very soon so now that we have that under control it's time to create a form where we can add the oinks by the way have you subscribed to my channel i would really appreciate it if you did and if you like this video please click like below because it really helps me grow the channel so i will begin by including vue.js to our project so i go to paste.html and below the content i create one more comment scripts and scripts just have a clean section script src i will just use a cdm to include vue.js cdn dot js deliver net npm view this view.js and close it below here i want to create one more block just like this so i can insert data here from seven pages this should be called script oops script like that so now i can copy this and go to the feed dot html and below here paste this and inside here i can create javascript so i can do this by saying script and new view create an instance of view element should be hashtag feed app you can go up and edit here id feed up since django and vue.js both use double curly braces to insert data i need to change this for the view js so i said daily meters create an array i like to use double braces like this because i think it's i think it's pretty and then a data return i want the list for the oinks and one for an empty body like that below here i want a method for submitting link so submit link console.log submit link like that so that's the view js right here up here and it also do some changes i can just remove this for now and in here as a div class wrapper form form v on colon submit.prevent submit link so when i submit this form i want to call this method in here i want the field for the body field div class control text area class text area the model is body place holder what are you pointing and close the text area like that below this field i want one more field for the button div class control button clause button is success so it's nice and green submit and then below the form node is already below and then below this div i want to create one more clause div clause wrapper links and in here i want to loop through links in this list div clause oink v for wink and oinks just a simple paragraph oink dot body and save before i do anything more here i just want to include some css to make this a little bit prettier first i need to create a couple of folders and a css file create a new folder in the root here new folder static and inside the static i create one more file called a folder called css and inside there i create one file called main dot css then i can add a background to the body just to check that everything is working for the background f9 f9 f9 so it's light gray to test this i need to go into settings.pi and tell django where to look for the static files so below the static url says static files dealers equals then a list base there slash static save and then i need to go into the paste.html file again on top here i said load static so django loads the static files and then i need to include the file below bulma so i say link rel style stylesheet href then static css main.css and close it so this function will look for a folder called css inside the static folder and inside there a file called main.css so i can save and go to the browser to test this yes as you can see up here i have a light gray background on the content then i want to add some more css to that file just to make sure that the oink looks a little bit better dot wrapper oinks margin top 30 pixels wrapper oinks not oink so i select all of the oink inside of that wrapper margin bottom 10 pixels padding 20 pixels border radius can be set to 4 pixels and then the background should be white also going to use a name inside of the oink so select the dot name font weight bold and info which is the date when it was added font size 12 pixels color aaa like that so to test how this would look i need to change the feed a little bit so over the text i want to create a new paragraph close name in here i say oink dot poinker which is the name of the one who you submitted p class info poink dot created at and save and i also need to do a little bit more down here in the view js pointer which is me just pause in request.user.username and created it can just be static now so if i go ahead refresh nothing happens because i still don't have any links in the list but just wanted to see that there was no errors but if i click submit you will see that i call this function so in here i can say if this dot body length is greater than zero then i want to create a new object called oink create a body this dot body winker this dot pointer is a references to these fields created at this dot created at and then i can close that like that below here i said this dot oink oinks dot and shift point so i put the oink i just created at the beginning of the list instead of the end below here i want to send to backend for saving and when this is done i said this dot body equals empty just to reset it so if i refresh no testing submit get admin which is me test and it was just submitted perfect so it looks a little bit better now we can see hero to oink and similar next step now is to create an api endpoint to receive the data and to add it to the database so i go back to visual studio code and inside feed i want to create a new file called api dot pi i want to keep things as simple as possible so i don't feel the need to implement django rest framework or something similar the reason why i put this in a file called api.pi instead of the regular reviews.pi is that i want to separate the views used for jsonresponse you can call this file whatever you want it's just that when you see api.pi you immediately understand what it is therefore so first i want to import json and i want to import a couple of django modules from django.http import json response from django.comtrib.org.decorators import login required because this view here requires login so i can just set that like it just that login required and then def api add link request and inside here i want to get the data from the request so i say data equals json.loads request.body body which is the link equals data body and then i create a new oink by saying link equals point.object.create body equals body created by equals request request dot user also need to import this model so i can say from dot models import link i can say dot models because i'm in the same folders in the same folder as the models dot pi file and when link is created i can say return json response success true and save and then i need to import this view into the urls.pi from apps.feed.api import api add oink okay and then below here api path api slash add link then i pass in the name or the order view and set the name for this and save and then the last step is to submit the data using javascript or vue.js so i go back to feed.html below here i call a function called fetch api add link which is the route or url we just created method should be set to post headers content type is application slash json and then x csrf token this is just some security csrf token like that we'll set credentials same origin body json.stringify and that should be this dictionary or list that okay sorry there we have it and this is done we call the function then response fat arrow function console.log response we can see it in the console what happens and if there are any errors we want to catch this error console.log error and save so everything seems to be working here so i can go to the browser and refresh okay it doesn't look correct you shouldn't see this yeah there is missing parentheses it's there so then i can save refresh okay now it looks good so first point does this submit got the 200 status back from the server everything seems to be okay if i refresh it's gone and that's because we don't have any functionality to get the links from the database yet but at least it's working so if i go here refresh you'll see that the first link created by admin is in the database so since everything is working now i can start working on getting the points from the database so if i go back to views.pi inside feed i can import a model up here from dot models import oink and inside the feed as a user ids user ids equals pass and mine request reducer id because i want to get links that i have written as well so for oinker in request.user.anchor profile dot follows followed all user ids dot append oinker dot user.id so what happens here is that i loop through everyone i follows not that i follow anyone yet but it's just for later and for everyone i follow i append their user id to this list and then i get the oinks from the database by saying links equals point objects dot filter created by id underscore underscore if one of those ids is inside the list user ids and save also i don't need to save yet because i need to add a dictionary below here like that so now the oinks should be available at the front end so i can go back to feed.html again and above here i can loop through them by saying four point in oinks and four just like to close this before i do anything more div class point p clause name link dot created by dot user name paragraph point body info create that add oink dot created that close this and save so if i go back to the browser now refresh we will see the oink i created a couple of minutes ago the date format doesn't look good so i want to implement the django filter called natural time django has this functionality already but i need to activate it you could also use a filter called time synth but i don't like this as much as natural time you can try both and see which one you like best to activate it i go to settings.pi and inside installed apps i say django.contrib dot humanize and safe and on top of feed i say load you nice like that and after create that adjusted pipe natural time natural time save so if you now see this date on a refresh just at four minutes ago it's perfect looks much better okay to make it possible to find other oinkers i want to add a search the search view can be located in the feed app as well so we can just go to views.pi login do any login for this yes login required def search request then i get the query from the parameters now from the url request dot get dot get query just shouldn't crash if it's empty so therefore i add this if then query greater than zero i don't want to run it if it's empty linkers equals user.object filter username i contains equals query so it gets all username that contains the query set i because it's not case sensitive else pointers equals just empty list then i want to create the empty now a dictionary for the query and the oinkers next i need to return and render this plus in the request parameter feed slash search html and add context here so next step will be to create a template search.html just want to go up here and copy this don't need a feed up just close this sorry dave and block you can add a title here h1 clause title search below there i want to show the search term query just add a line to separate the top from the content in here i want the search form form method get action can be the same page just be sure as a url search close to form div class field since this is a get and not post we don't need a csrf token div class control input type text clause input name is query value passing the query like that so then i can close these two below that field i want a button for submitting the form div class field div class control button clause button is success so it's green search below the form i want to list out the oinkers div class search results look through them by saying for oinker and winkers just add a paragraph linker dot user name and for save if i fresh now i should also sorry i should also add the button up here in the in the base so next to here i say a href url search close it close nav bar item search and save so the last thing i need to do now before i can test this is to go down to urls.pi and import the view search next to the feed i can copy this just say search replace and replace and save so now i have a new menu item search search admin name user is not defined okay i might have forgotten to import the user model up here yes from django that contribute both models import user just refresh and now i have the admin user because i search for admin for search for code code with stein will appear here so we've made a lot of functionality now but there are still a ton of things left to do the next thing i will implement is profile i want to make it possible to visit the profile so i can see the profiles links followers and who the pro profile is followed by also i want to make it possible to follow a profile similar first step is to create a view for this okay if i go to views.pi inside the oinker profile i can begin by importing two things from django from django let's contrib dot user now contrib dot auth dot models import user and i can also add get object or 404 that's the shortcut behind or after render then i can create the view def linker profile request and a username and then i get the user from the database by saying user equals get object or 404 plus in the user model and username equals user name if that user user doesn't exist i will get the 404 error context just create the empty no simple dictionary user user return render request linker profile slash anchor profile.html and pass in the context and save so then i can import this to the urls file below here from apps.anchor profile those views import winker profile and i can add this below here part you want to be prefixed with you and then i will get the str which is a string and the name of that should be username this is a reference to this username here slash and then pass in that name of the view and also set the name like this so then i can save that and then i can go up again here create a new folder inside there templates and inside the templates folder create one more anchor profile and inside that winkerprofile.html which is the template name i want this to extend the base template just like everyone else extends core slash base html until you load human eyes because i going to show that here too block content and block then i begin by creating a container dave claus columns if class column is 12 h1 class title then user dot user name i want to show that as the title create one more columns if column is eight i don't want this to be as wide as this one dave claus prepper points and in here i want to loop through all this this user's oinks so i say for oink in user.oinks.old so i don't need to go to the back end to get this i can just say this div close oink oink like that p close name link dot created by dot user name p info link dot created at pipe natural time and save so but before i continue i just want to add a button in the menu so i can go to my own profile so i can go back to base.html and after feed create a hrf url oinker profile and then i just put in my own username request.user.username class clause nav bar item profile and save so if i refresh now i will get the new button up here okay forgot to do something in the oinker profile it should be end for of course so now i see the username and all of the oinks from this user maybe we should also add a counter to see how many the user follows and are followed by so up here i guess p followers user dot oinker profile dot followed by account and follows user.oinkerprofile.follows.com count save okay i have zero followers and i follow zero person while we're at it let's make it possible to actually follow a user so below here i can test if i am this user if user not equals request dot user because i don't want to to follow myself a hrf follow winker oops url follow anchor user.username clause button is success so it's nice and green follow and save now i need to create this view so if i go back to views.pi in the oinker profile folder i can say def follow anchor request pass in the username and i can get the user just like i did up here and then i can say request dot user dot oink or profile because i want this to be added to mine follows dot add user to anchor profile so i add this user's anchor profile to the list of anchor profiles i follows then return redirect linker profile username equals username so i'm redirected back to the user i was at this should definitely require login so i need to import the decorator from django.contrib.org.decorators import login required and save so now i just need to import this to the urls and then as a part you store username follow passing in the view and then give it a name and save so now we can test this so i don't have any buttons here but if i go to code with stein okay reverse not found okay yes sorry i forgot to add this one so now i see a follow button if i click it redirect doesn't define sorry should be added up here as a shortcut so there now i have the followers one so code design has one followers if i go back to mine as it follows one perfect so now we can also make it possible to stop following a user so i can go back to views.pie and say login required def unfollow linker request username and it's almost the same code is up here so i can just copy all of that but instead of saying add here i say remove and save that's it so i can copy this now go to the urls import and follow anchor up here and i can also just copy all of this say and follow and follow and and follow so now we have the possibility to unfollow a user but also need to change the template a little bit so inside here i need to check if i actually follow this user if request dot user dot anchor profile in user dot anchor profile dot followed by all else i will show this button and if so if my profile isn't in the list of followed by i will show a stop button or unfollow url and follow linker user dot user name clause button is danger unfollow and save so now we can test this yes i have unfollow button and this number goes up and down that's perfect so everything seems to be working so we can continue to the next task and the next thought is to make it possible to see a list of followers when oinker is following so i want to be able to click this to see the list i will begin by creating the view so i can go into views.pie and say death follow words request user name and get the user like this again return render request linker profile slash followers dot html just post in this user save and then i can create the template followers.html i can go in here and just copy a little bit so i don't have to write all of this again then just close this just prefix this with followers below here i want to show the number of followers just so i know it user dot anchor profile dot followed by dot count below here create a new columns if clause column is eight and here on to loop through the oinker who this peop who this anchor is following so i say for oinker in user dot anchor profile dot followed by all and four just close that loop p a hraf so i can click this profile url anchor profile oinker.user.username close the link linker.user.username like that also i can use a cool cool template function that django has i said just say empty p sorry you don't have any followers but this isn't something i want to see if i'm on someone else's profile so we need to check here if request.user equals user then i want to see this if i'm some on someone else's profile i want to say user.username doesn't have any followers then i close this like that then i can create a link from the anchor profile to this so up here say a hrf url followers pass in the user.username and i can close the link after there and then i save it and then i need to import followers into the urls that's the last thing i need to do before i test this just copy one of these followers followers and the name is followers so if i refresh now there's something wrong followers is not defined no because i forgot to import it up here refresh now i can click here followers for coded stein number is one and there is the user so perfect now i can do the same for the follows so i go back to views.pi and i can copy this i can just follows follows say maybe i have a d here so it's correct i can just import this so i don't forget it import and then i copy this path follows follows follows and i can create now i can copy this template follows html and then i need to replace a couple of things here like that and then i need to say just follows there and i want to loop through follows sorry you don't follow anyone that's not correct to just be you don't follow anyone and username isn't following anyone like that last step is to go back to oinker profile and i can copy this link paste it before follows and close it behind there and save so now i can test this follows so perfect now i have a good loop so i can go through all the profiles like this also want to make it possible to click this user so if i go to search.html beforehand hrf url linker profile poincare.username and close like that refresh so now we can click this it's perfect i want to make it possible to have profile pictures to do this i need to create a new field on the oinker profile model so below the follows field i create one more avatar equals models dot image field upload to upload and then i want to make a possible to have this empty so i said blank equals true and null equals true in case user don't want avatar so save this before i do this i need to make sure that i have pillow installed this is a package python uses to handle images so to install it as a pip install pillow [Music] then i can update the database again python manage.pi make migrations and python manager pi migrate so now i got a new field avatar on the oinker profile the next step is to create a profile edit page i will create a link in the paste.html to this first so if i just go up here paste.html and the last link here can be a agrf url edit profile like that just close this close nav bar item edit profile and save and then i can create the form and the view for this i will use something called a model form this is a class from django that helps us generate a form based on database model we'll begin by creating a new file called form inside oinker profile new file forms dot pi and then i need to import forms from django from django import forms and then import the model from dot models import linker profile and then the clause clause winker profile form plus and forms dot model form in here i create one more class meta which is just options for the form model equals link profile and the fields i want to show here is avatar so this is a tuple and it's at a comma here since that requires more than one field and we can save this so copy this close it it's not very complicated but does the job this will generate a form with one field which helps us upload files so if i go now to views.pi on the top here i can import this form from dot forms import linker profile form and then i can create one more view first add the login required decorator def edit profile pass in the request parameter i want to check if the request method is post and if it is as a form equals on your profile form request.post request dot files and since we're updating this form and not creating a new one and it said instance equals request but user profile so i pass in the data we already have and merge it with these two so if the form is valid then i call form dot save so now the form is saved and i can return the user to its profile return redirect you see that i have this imported up here yes i want to return it to the view called oinker profile and then i pass in username equals request user username if the form isn't valid as a else oh sorry if the request isn't post i say alice form equals oinker profile and i pass in instance here as well request with user.oinker profile down here want to create a dictionary context e equals that was in user request dot user form is form and then i need to return and render this return render request linker profile slash edit profile.html and pause in the context dictionary and save next i need to create the monkey profile edit form so create new file edit profile dot html can just go in here and copy a little bit so we don't have to write all of this again title can be edit profile and block i don't need humanized hairs i can remove that below here i want to check if the user has an avatar if user dot linker profile dot avatar figure class image is 128 times 128 this is a bulma clause that sets the image to be maximum width of 108 and maximum height of 128 image source user.oinkerprofile.avatar.url this will automatically generate the path to the image and if here i need to include the form form method post and type multipart slash form data we need this because we're going to use files post no action dot this is a post request we need to include the csrf token then we show the form as a paragraph and then a button dave class control sorry the plus field in here dave claus control button plus button is success changes div like that okay i need to do a little change in the settings file as well because you need to tell django where the uploads folder is located so just save this template file go into settings.pi and at the bottom here with the static files we say media url media just like the static files media root equals base media the last step now is to include this page and the media files in the urls section so go into urls.pi and import a couple of things from django.conf import settings so i can reach the settings variables and i need to import from django.com urls urls dot static import static and at the bottom of the url patterns i say plus static settings dot media media url document root equals settings dot media root so this will help me serve media files in development when we are going live we are going to use nginx instead of this development server to show how to host the files and then soon ready just need to import the edit profile view i did profile and i need to add it below here so now i can just say path edit profile and this profile name edit profile save so now we can go and test this fine now refresh the eraser okay and start server again refresh edit profile so now i can choose file just go into oink oink find my profile picture save changes okay so now it's redirected back to my profile i want to show the profile picture here but i just want to check here that it's working and yes it is so that's perfect so i can go back to the edit profile file copy this i'm going to own your profile.html and below the username i can just now save refresh and now it's showing here too you can add the hr below to separate it a little bit that's perfect so i want to show this avatar other places as well for example below here in the in the loop for oinks i want to change this a little bit so in here i said article clause media figure clause media left p class image is 64 x 64 and here i want to check i can just copy this and in src user.linker profile avatar url and if and change this a little bit more div class media content strong and here i want to insert the username below or next to it as a small and this is the time like that br for brake line point body i can just remove this and save so now the winx looks a little bit better i can copy this and make sure that it looks this way inside the feed as well so if i go up to feed.html and paste it here sorry it was supposed to be inside the class oink like that but here i need to change a little bit because i need to say oink dot created by dot link your profile avatar to just replace this and save so i think i can go to feed yes it's working there as well and i need to update the this view here too i can copy again paste it just simplify it a little bit like that body should be there link created it now i can remove this and here just remove this test and almost all of this can go away as an image and i say src like this because i want to bind this to oink dot avatar and save so now i think everything there should be okay but i need to change the script also because i need a field called avatar if request.user.linkerprofile.avatar that request.user link profile dot avatar url and if and inside this oink array say avatar this dot avatar let's save so refresh testing submit okay it was added there that's almost good it's just that i want this to be above the old ones so just move it up here like that and save so now we have everything we need for the profile pictures one thing i think is missing is the possibility to like an oink to make this possible i need to add one more time model to the feed app so i'm going to models dot pi below the wink christian remodel class like models dot model any reference to oink oink equals models dot foreign key link related name likes on delete models dot cascade so when we delete an oink we also delete its like created by you can actually just copy these two and replace the likes like that also i don't think i need any ordering there so i can just save and go to the command line and update the database powering make migrations and then migrate i can run the server again i don't think i need to register this with the with your in django admin interface i would like to be sent to the server using vue.js so the first thing you need to do is to create a new api function so in here create a new one login required oops def api add like request i need to copy this poinc i id equals data oink id and then i want to check that the user hasn't already liked the oink if not like dot objects dot filter oink id equals oink id dot filter created by equals request but user accessed so it checks if there is a like with this link id and it's created by you and if it's not we create a new one saying like equals like objects dot create link id equals oink id and create thereby is request user json response equals success to set this to true all right like that return json response and pass in there i can actually just do this so it's a little bit cleaner and safe and then i need to import this to the urls so we can access it from the front end let's just import it there and then i can copy this path and like like and like so now we can access it from the front end so everything on the back end is ready so we can add a button for this for on the oinks so if i go to feed.html and go in here into the loop in the four oinks below here is a br a at click like oink dot id link id like sorry close like so we check if this wink is in the list of liked oinks so we only show this if it's not in that list spam the if liked links dot includes so again we check if if the oink list now you will check if the oink id is in the list of liked oinks so i pass in oink dot id liked so we don't show the button if we have liked it we just want to show a text and then i want to show the number of likes this is the custom id so we can access the content link.likes.com likes and save and then i need to go down and change the and add some script below then i need to go down to the dead array to create the likes array likes oh sorry liked links then i say for point in points if poink dot liked point dot id add a comma here and if and four so here we loop through the oinks and if we have liked this oink we added to the list of liked oinks so i'll show you this attribute in a minute i just want to finish the submit like oink or like oink function this dot liked push pause and so we know it's an integer link id and then we can send this to the back end i'm going to create a dictionary for oink equals link id link id and use fetch to send this api and like this is the port we just created method just copy this actually here we can just copy the whole function and paste it like that yes so everything here should work and then i want to update the number of likes so icons yell which is just short for element document dot get element by id likes plus point id this will get this field here this small so i want the content of this const likes equals parse and element.inner html dot split so we can remove the likes text like that plus one yeah that inner html equal likes plus likes and save so this will increment the number of likes with one and then append this text at the end in the views.pi file if i go there where i loop through the oinks i need to check if i liked it so here i say for oink in links likes equals oink likes dot filter created by id equals request request.user.id if likes dot count is greater than zero rank dot like equals true else link dot like equals false and save so i think i can go to the browser now to test this very fresh there is nothing here so i've done something wrong okay i should typo and click that click yes that looks better okay so if i now click like it says one likes but i got the internal server error because like is not defined and that's because i forgot to import like there we can refresh try again no manager has not created no sorry create sorry for the typos okay now it seems to be working so it's just like that one likes if i refresh it still says liked so perfect that means everything is working so then i can go to the oinker profile and do the same thing there so if i scroll down go into views.pi and inside the oinker profile i said links equals user dot oinks dot all for i can copy this i don't need to type all of this again like that i'm going to add this to the context and save and then i need to go into the link your profile.html because now i can't loop through like this to just replace this with points and save and then i need to copy this and paste it behind or below the body and i also need to copy the parts below here this one so i know which one is liked okay i actually don't have any scripts here so i can copy all of the script tag from feed and clean some because i don't need to submit like that but i need a like i can remove this oinker profile app and i need to set an id here and save so now i think we can go to a profile as well to test this so my own profile try to click like there yes yes it's working perfect so now we have likes in our project i want to improve the search a little bit because i want to make it possible to search directly from up here in the menu so if i go to base.html and above here i create a new element div class navbar start then close nav bar item and in here i create the form form method get action url search and to point it to that part div class field has add-ons save class control input type text class input placeholder is search name query and then below this control create one more clause control which should be the submit button a clause oh button close button is success it's nice and green search that's it but i want to just remove the link because we don't need that anymore refresh search and it's working it's perfect i also want to make it possible to search for oinks as well so if i go back to the views dot pie and feed instead of just searching for oinkers i also want to search for oinks so in here the oinks equals oink dot objects filter body like contains query links and pass it in the context so we have it in front end as well so then i can go into search html and on top here in the search results i want to say if not oinkers and not links show a paragraph no results please try a different search term term like that l and if and then i want to check if there are any oinkers if one occurs and i want to show a title strong winkers i can loop through like that and live below here to look through the oinks so i say if oinks and if and i want the title here as well strong oinks div claws wrapper oinks standard loop through them for oink and points and four and i think i can copy the one from the feet because it's very similar so just copy all of this go back to search and paste it in the loop i don't need a like inside here so i can just do that i also want to make it possible to click to click a link sorry to click the username so here onto the a hrf url linker profile link dot created by dot user name and then i close it after there and save so we can test this now but probably is wrong it should be body okay so test so here you get the tests and i can click this one perfect would make it possible to click them as well here in the profiles and in the feed so i can just copy this and go to the feed paste it there and close it behind like that and i don't need that in on your profile because you are already in a profile but if i now click feed i can also click them out there so now the search works a lot better than it did perfect another important thing for social network is the possibility to send direct messages so now i'll make this possible i will begin by creating a new django app so i stopped server create a new folder apps slash conversation python managed and managed pi start app conversation should be located here hit enter and then i can go to the settings file and register this with django so a pair apps dot conversation like that so now django know that it exists so now it's time to set up the database models so if i go into apps conversations models first i want to import the user model from chango.comtrip dot dot models import user clause conversation models dot model this should have a users field models that's many too many fields so i can add both the users in the conversation user related name equals conversations and i also want a modified field so i can sort them modified at models dot date time field auto now equals true so instead of saying auto now add i say auto now so it's changed every time i save an object clause meta ordering create list minus or dash modified that also wants one model for the conversation message conversation message models dot model and here i want a reference to the conversation so i say conversation equals models dot foreign key copy and paste object related name equals messages on delete model.cascade so when delete a conversation will also delete the messages content is the message itself this should be a text field models.txt field i want a created at models.date time field auto now add equals true so this will be added automatically when we create a message created by this will be the sender models dot foreign key user related name messages on delete models.cascade it might be stupid to delete the messages when we delete the user but it will do for now i want a close meta here as well ordering created at so we have the newest one at the bottom like that and then every time i send a new message i want to save this so it's get changed every time to do this i say def save self args k works self dot conversation dot save so i call the save function on this object so it will trigger and modify that will change super conversation message so i save this to save orgs okay works and save so now i can update the database make migrations migrate and run server i can also import this to the django admin interface from dot models import a conversation message admin.site register admin.site.register message nice so everything with the database seems to be working now so we can create a basic view for the conversations so i can just copy this import go to views.pi and paste it here also want to import the login required decorator from django.comtrib.both decorators import login required create a new view def conversations request then i want to get all the conversations for the logged in user request that user talk i can say conversations because in the models we have this related name which is an index in the database return request conversation slash conversations.html plus in to conversations like that perfect so now i just want to add this to the url patterns so copy the name of the view scroll up here from apps.com import conversations you can add this under edit profile path conversation slash pass in the view and give it a name save then i can create a folder and a template for this so if i scroll up again create a new folder in here templates new folder in there conversation and then the fold know the template name conversations.html so i can probably just go ahead and copy the top of a different template close it and the block title here should be conversations below the title i want a conversation list div class conversation conversations list in here i want to loop through all the conversations f4 conversation and conversations just close this before i forget it div close conversations list item and here i want to get the other person's username so i need to loop through the users in the conversation for user in conversation dot users all if user not equals request dot user then i know it's the other user so i can print the user.username conversation dot modified at pipe it into the natural time filter so i need to load sorry load hue my nice like that so we get a more pretty time close the end if and close this m4 if there are no conversations you can use the empty tag like this just say no conver sessions and save last but not least we need to add a button for this up in the menu so if i open up based.html and after the feed as a a agrf url conversations plus nav bar item conversations save so if i now go to the command line okay here's an error this is use dot pi here should be equal sign and then i can run the server go to the ongoing page and now have no conversations so the next step will be to add a button on the oinker profiles to send direct messages so i can now go to oinkerprofile.html and i only want to make it possible to send message if the profile isn't mine so in here i check this already i can say aagrf url conversation will create this soon pause in user.id this is the other user's id close button is info send message so i can't actually test this because i need to create this view so i can go back to views.pi inside the conversations i also want this to require a login request here i want a user id so the first thing i want to do now is to get all the conversations for my own user conversation that object.filter users in request.user.id so now i get all conversation where my user id is inside the users which is this field and then i can change this again to say conversations equals conversations dot filter users in user id which is this one which is the other users id i do this to check if there are a conversation already if not i want to create one so if conversations that count is one we have a conversation so we can just say conversation equals conversations zero else so i get the first one in the list which should be just one if not i want to get the user recipient equals user objects dot get pk equals user id conversation equals conversation dot objects dot create just create an empty one and here i want to add sorry users.add request.user which is me conversation.users add recipient so i add the other user as well conversation.save so now it should be ready to be used return render request conversation slash conversation.html just pause in the conversation save so now i can import this view to the urls pattern just scroll up paste this there i can copy this after the slash i want an integer called the user id which is this one and i want the conversation view and give the name conversation so that i can save and then it's just the template left here so if i can just go in here now to the conversations and just copy the top create a new file conversation.html close everything here and block and save and inside here i want to loop through all the messages so i first created div class messages just to wrap them and then a loop through for message in conversation dot messages to all and i get them this way because in the models i added this related name messages which is index so we should be working div class oink i just give it close orange so i get the same style as every other places particle clause medium i don't know the figure clause media left p clause image is 64 times 64. if the user has a profile picture i want to show it if message dot created by winker profile avatar just close the end ink src message dot created by.winker profile avatar dot url so now we should show that image there div plus media content dave claus content paragraph strong to show the name at the top message.created.username after that as a small message dot created at pipe natural time the line break message dot content and every field here is closed and then below this for loop i want to loop through the view messages so here i say dave plus point link v4 message in messages i will create this soon then i can just copy all of this and remove this line i know this will be my picture so i can change this to message.avatar and to get that i need to bind the src to this field here i can say message dot pointer and message dot created at i know this is a long template but we will test it soon and message dot content save and then the last thing and then below this div i want to create an hr just to separate the submit form form v on submit dot prevent this is this is the send message form submit message sorry like that dave claus field team claus control text area clause text area v model content placeholder your message now we can close the text area below this i want to show a button tab class control button close button is primary so it's nice and green scent so it's a bit success so then it's nice and green so i forgot one thing at the top here and that is to set id conversation app save so we can test this now i think just to see that everything is working code so i go to code with stein send a message name user is not defined okay i forgot to include the user model from django.comtrap.models import user refresh okay i have a typo sorry conversation nature that's your role time it should be okay it's almost working but we need to add some more view but we have the template is working okay so if i go below here let's say block script close the block script new i can say var conversation app equals new view element should be conversation app which we just set up here also need to add the delimiters here and a data array messages can be an empty array for now content which is the text area oinker which is me request.user.username created at just hard time hardcode now avatar if request.user.oinkerprofile.avatar i want to add the url request that user.oinker profile.avatar and if and i want the method to submit the link no the message to the back end so i create a new methods submit message if this dot content.length don't want to submit it if it's zero characters voir message equals content and this content winker this dot anchor created at this dot created at avatar this dot avatar and then i want to append this to the beginning of the list this dot messages and shift message and when that's done i want to send it to the backend fetch api add message method is post and now we need to set the headers content type application just json x c s r f token csrf token credentials same origin and then the body json.stringify message which is this then i need to call this response create the fat arrow function console.log response and if there are an errors i want to catch them like that and then i console.log error and when it's sent in i want to empty it so empty the content field has a list of the content equals empty if i go to the browser now we wouldn't see much since there are no data there but i can create a view for the api so we can test this more if i add this now nothing happens okay also have a problem with the url for the image it's supposed to say url there if i refresh try again this is looks much better but i still need to fix the api endpoint so inside the conversation i need to create a new file api.pi import json from django.http import json response from django.contrip.org.decorators import login required then i can create a new view dev api add message request also i need to import the conversation message model conversation message data equals json.loads request body content equals data content conversation id equals data conversation id then i create a new message pressing message equals conversation message dot objects dot create conversation id is this one content equals content created by equals request.user then i can return json response success true and save then i need to import this to the urls section from apps.conversation.api import sorry import and i can add it down there path api add message pass in the view and then add a name and save so now i can refresh first message send okay i got an error sorry i forgot to add the slash there try again first okay now i've got the 500 error because i forgot to add the conversation id in the api it should be added in here sorry so if i just do this then i can say conversation dot id i think because i have the conversation from django so we can try that refresh first so now we go to 200 which means everything should work so when i refresh i get it from the database okay now i just want to add a link from the conversation in books to the conversation detail page so here i can wrap this paragraph in here in a link a hrf url conversation and then i pass in user.id and then i paste it there save so if i now go to conversations i will see that i have a conversation with code with stein click and here it is perfect right now if i get a new message or someone new is following me i don't know about it before i check it's time to introduce notifications at least every time we refresh the screen we can see it in the menu if there are any new notifications i will begin by creating new django app so stop the server make a new folder apps notification python manager pi start app notification apps notification i can also register this with django and settings.pi file apps dot notification and save so now i can set up the database model so scroll up and find the notification folder and models.pipe so first i import the user model from django django.comtrip both models import user class notification models dot model then i want to set up some choices here if it's a message notification or if it's a new follower or if it's a like then i set up a new tuple with all of these message this label will just show in the menu in the django admin interface like that and then i need a couple of fields for the model 2 user this is the receiver models dot foreign key user related name notifications on delete models dot get cascade notification type equals model.char field max length equals 20 choices here i want to make it possible to select between these three this red to make a possible to see if the notification is read or not models dot boolean field default equals false created at equals models dot date time field auto now add equals true created by equals models dot foreign key user related name created notifications on delete models dot cascade almost delete like that then i wanted a meta clause to set up the ordering minus created at the newest one is on top now i can save this and update the database make progressions and python managed by migrate perfect i can run the server again you can also register this model with the django admin interface from dot models import notification admin.site register notification and save how do you create the utility file where i add notifications to the database this utility file can be referenced from other places in the app or the project so inside the notification folder create a new file you tell it or utilities.pi and here i import the database model like that def create notification pass in the request to user and which notification type to create then i created was a nodetv application equals notification.object.create to user equals to user notification type equals notification type created by equals request dot user and save if i now go to the api file for the conversations i can implement this for new messages api.pipe and up here first import it from apps dot notification dot utilities import create notification like that and then i need to loop through the users so i know who to send it to to user equals none for user in message dot converse if user not equals request but user i can actually just send it in here or create it there so i don't need that then i just say request user and message this is the type of notification so now i can see there is no error i can try to send a message to code with stein hi again send okay i got an error conversation attribute just no okay this is an api.py message.conversation right again okay now it was added perfect if i go to the admin interface now i can see in here that there are one notification to code with stein to type message it's not read yet and it's created by me which is admin perfect so i want add this functionality when we start following another user so if i go to to anchor profile views.pi and up here import from apps i can just go to api and copy this like that and then below here when we follow an anchor create notification request and then the user follower and save and then i do the same with the likes so if i go to to feed views.pipe and first import the great notification and then i go no it's not here it's in the api dot pi there sorry say there and down here inside here where we have done the like create notification request and oink okay that's not gonna work i need to get the link first link equals oink dot objects dot get pk oink id and then i just put in the oink this and say created by like so the one who created the oink i like should get in like should get the notification so that's perfect there's no errors so now let's make it possible to get the notification a place up in the menu since the menu is always available on all pages i don't want to include a new query set for all the views so i want to use something called a context processor this is globally available data in django i begin by creating a new file inside the notification app called contextprocessors.pi context processors.pie and here's the from dot models import notification create a new function def notification [Music] request if request that user is authenticated authenticated sorry then i want to return notifications request.user.notifications does filter is red equals false if it's not authenticated i just want to return an empty list like this before i can use this i need to register this in the django settings file so i go down here i found find the templates list and at the bottom of context processors here i say apps dot notification dot context processors dot no the applications like that save everything still looks okay now it's time to show this up in the menu if i go to base.html and before the feed here i can say ahref url notifications i want this to link to a page class nav bar item no notifications and here i want to show you notifications count so with the notifications.com this is a reference to this so it should be notifications sorry like that and this should be also plural did i say that there yes so here i did it correct so now if i try to refresh i think i get an error yes because i haven't pull object is not callable that was not the error i expected so i will come back to it i just want to create a folder and template and a view for the notifications so in the notification folder create a new folder templates and notification and a template called notifications.html i can just copy a little bit here no tv occasions and block and at the top i can first say if not notifications n p no no you have no notifications and if they've close wrapper points and you look through them inside here for notification and notification and then i say article clause media figure clause media left p clause image is sorry is 64 x 64. if notification dot created by dot poinker profile dot avatar and i want to show and picture ink src paste this url and below the picture if class media content div clause content p if notification dot notification type equals message and if then on a grf url notifications so i look through the same page as i am on now just pass in some new parameters behind here so i can set the notification to red conversation this is the page i want to redirect to and note the vacation equals notification dot id in here i say strong identification dot created by dot username sent you a message break line notification dot created at natural time so now i see who sent it and when it was done so then again copy this paste it there i'll save notification type is follower then i want to go to oinker profile and replace this with started following you i can copy this again for the likes like i also wanted to go to user profile but i want to say liked and point you wrote like that and at the bottom here i can say empty now i already have the check at the top so now save this and then i just want to change the css a little bit because up here i want to say notif dot notification prepper dot media so this will also get this styling close that next will be the view to render the html and redirect the users so inside the views.pi i first include the login required decorator from changgo.contrib.org import login required and then it import the redirect shortcut i need to import the models notification create a new view dev notifications request go to equals request.get.get go to notification id equals request.get.getnotification 0 is default if go to isn't empty i know that i should redirect him then i get the notification from the database get pk equals notification id then i set it to be red notification dot save if notification dot notification type equals notification dot message then i want to redirect him to a conversation so i say return redirect conversation pass in the user id from notification dot created by dot id so we will be returned to conversation with the one who sent the notification alif notification dot notification type if that is a follower return redirect link your profile user name equals notification dot created by dot user name or if it's a like notification like return redirect poinker profile username equals notification.2 user equals username because you want to redirect it to your page because you are the user so dot username and then last but not least i want to render the notifications html file notification slash notifications.html save so now i can go to the urls to import this from apps.optification.views import notifications then i say here this plus in the view give it a name and save path sorry okay everything looks good still have this problem request that user is authenticated okay it's inside the context processor it's just supposed to be there because it's not a function okay so now the conversation is working i have no new notifications but if i try to go here to my profile you can unfollow him follow if i now sign out sign in again with code with stein he had two notifications started following me and he sent me a message if i click send a message i get sent to the conversation and there's only one notifications left it's perfect so now that we've implemented notifications we have come a really long way on our project there are a few limitations on what we can implement in our project but everything takes time the last thing i want to implement are mentions if someone mentions our username you should also get a notification i'll begin with the database model for the notifications so i go into notifications and models.pi up here i create a new variable mention equals mention and then i added below here as well mention i don't need to update the database for this but i need to update the template so go to notifications scroll down here and i can just copy this because i want to go to oinker profile when someone has mentioned me so just replace mansion like this and then to replace this with mentioned you in an in an oink and save so then i also make it need to make it possible to toggle the read status and redirect the user and that happens in the views.pi so below here i say alif notification dot notification type equals notification dot mansion this is the model and this is just the variable inside here and if it is a mention i want to return redirect poinker profile username is notification dot created by dot username and save and then the last step is to make changes to the api inside the feed put into the feed folder there and into the api.py file and here where i've added the oink i first want to import something called import re which is short for regular expressions i already have the create notification and i have to import the user from django.comtrip.org.models import user and then below here i can say results equals re dot find all okay this is kind of a tricky one i hope i type everything correct okay so what happens inside here is that i look for an at symbol followed by a word from with 1 to 20 characters this is hopefully a username and then i loop through the result for result in results and then i want the first one of them because result is a list with the add symbol and then the word print result this hopefully is a username then i try to get the user from the database if user.object.filter username equals result dot exists and i don't want the result to be my own username request.user.username and if it's not then i can create a new notification pass in the request user.object username equals resolved and the type should be mentioned like this so now we can save and test this if i go here to feed and then i can try to say hi at code with stein go back save everything seems to be okay for log out log in again with code with time i have a new notification admin mentioned you in annoying so this was working perfect so now it's time to start thinking about deployment the first thing you want to do is to add the code to github so it's easy to maintain and it also makes it easier to deploy i've just created a new repo in my github account called oink oink i will add a link to this in the description first i want to go to the root and create a git ignore file get ignore there are certain files i don't want to to be pushed to the github repo and first is db.sqlite3 all files ending with pyc also in the subfolders like this and save and then i can just go and copy you can actually copy all of this code go in here stop the server and just paste everything here and now the code should be pushed to my github account if i refresh now the code is here but only that file so i get status see all of this also needs to be added git add dot git commit version one i can say or something like that git push and if i go into github again i refresh all files should be located here now perfect so now i can start thinking about checking this out on my server so we just copy this go here and here i have signed in to the server i'm going to use the server with ubuntu 20.04 i will serve the django project using something called g unicorn this is perfect for django but this is not suitable for serving media files so it also uses nginx i will show you step by step everything i'm going to do i would begin by creating a user group and a user sudo group add system link group group add note group app and then sudo user add system git group id is oink group shell bin bash and the home for the user is slash link root and then the name of the user is oink user then i can create a group folder and go into it mk there link root link root this is the root for the whole project and where i want to create my virtual environment i create this by saying virtual env point oink three six sorry three six four and then i go into it and activate it source bin activate to make sure that i install the exact same packages on the server i can write p3s here on the local environment pip free this will give me the packages you can just copy this create a new file req.txt and paste them there and then adjust the pip install dash r requirement.txt sorry i've forgot i deactivated source bin activate and then i say this again perfect so now this is installing the same packages when the installation is done i can also install g unicorn which i'm going to use very soon pip install g-unicorn and then i can go to github copy this again in here is a git clone and then the environment so wing coin now i have the code here then i can create the database make migrations python manage pi migrate so now everything there is created you can try to run this by saying python managed pi run server 102 168.37 150. this is the ip address for the server so i just forgot to add this ip in my allowed hosts via coincoin settings.pi and i can also add oink oink.com in here should be without http run again and refresh so now everything there is running i will now show you how to setup g unicorn i'll begin by creating a new file called g unicorn start in the bin folder vi bin sorry after you go out there guys i have to stamp in the environment and then i say vi bin unicorn start and then i start to follow it this bin there pin sh then the name oink oink this has to be in quotes triangle there equals point root oink oink three six four point oink this is where django is located sock file link root point oink three six four run g unicorn. this will be created when we run g unicorn user is oink user group is link sorry link group num workers equals three have one cpu and you need to multiply the number of cpus with two and then add one at the end jungle settings module equals point coin settings django w sgi module is oink link dot wsgi timeout 120 seconds then i need to tell the script to go into django there and when in here you say source dot slash bin activate to activate the environment export eq jungle settings module just copy this equals django settings modules like that export python path equals django there colon python path like that run there equals their name sock file test d run there and if it not exist i created mk there dash p from there down here i say execute dot slash bin g unicorn dollar curly bracket django wsgi module close that one application new line here i want name new line workers num workers timeout all right timeout user equals user group equals group bind equals unix dollar sign colon dollars and sock file like that log level equals debug log file equals dash so everything here seems to be okay now if you don't understand everything here i suggest you try to read a little bit more about g unicorn it's not necessary to understand everything here just hope that everything is working save and close and then i just need to make sure that we can run this file ch mod plus x pin g unicorn start so i can try to run it by saying dot slash bin giancorn start okay everything seems to be working now i see that the link group now owns all folders here so everything should be okay there are a couple of different ways to make sure that g unicorn server is always running i will be using something good supervisor you install it by saying apt get install supervisor i have already installed it but you need to run this command install it at your server next i can go to cd etc supervisor conf d i already created a new config called oincoinc.conf we set the program name to oinkoink the command which is the script we just created the user to execute it we also have a log file in this folder and a couple of other commands when you're finished you can just save this and say supervisor ctl reread okay you will probably get that oink link is available then you say update and everything now should be okay if i run supervisor ctl status you will see that oink oink is running perfect so now the next thing is to install nginx you do this by saying apt get installed and gen nginx i've also installed it but you need to run this command then you go to edc slash nginx sites available and create a new file here called oinkcoink.com in here the first thing you do at the top is to create upstream and call it oink oink observer this is a reference to the socket file which was created by g unicorn so it's server unix slash oink root oink oink 364 which is the environment and then this will be created when supervisor starts the script down here we have a server listening at port 80 server name is my domain we have access log and error log and this is where we serve static files and media files at the bottom here we set up a proxy to transfer or forward the traffic to the g unicorn server as you can see here this is the name of the one at the top when that's done you can close it and go to upon folder and it decides enabled to enable the site you say alan s dot slash sites available oink oink dot conf oink oink dot conf i already created this but this is the command you need to run and then you just say server my service nginx restart and now everything should be working there so now i can go to the browser to test this oink.com i get a bad gateway okay so if i say if i go to link root link i'm just a tail logs g unicorn okay the something wrong here cd logs why can't i take the supervisor okay everything there seems to be working so i might need to restart the supervisor supervisor ctrl restart oink okay now it's stopped and started and now everything here is working so now you can enjoy your very own social network and as i said earlier there are a ton of different things you can add to this social network file attachments group chats make the search better email notifications possibility to change the username and similar you can also add retweets or re-owings as they would be called here and much much more so this is the end of the video i hope you liked it and that you learned a lot if you liked the video please click like below and feel free to leave me a comment i'd also really appreciate it if you choose to share this video with your friends and colleagues see you next time
Info
Channel: Code With Stein
Views: 21,565
Rating: undefined out of 5
Keywords: django, vuejs, djangoandvue, djangotwitterclone, twitterclone, codewithstein, vue, django and vue, django twitter clone, learn django, django tutorial, vue and django, django vue js tutorial, django vue js, django vue, python, python django, python django web development
Id: GClIzqdYNr0
Channel Id: undefined
Length: 196min 35sec (11795 seconds)
Published: Thu Sep 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.