Django signals for beginners | How to use signals in Django

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys luke here and this video is dedicated to all of you that are just getting started with django and want to learn signals so we will explore some of the most basic and commonly used signals on a project that we are going to create in just a second so at the end of the video you will know how to apply post safe pre-save many-to-many changed and pre-delete in your own applications so yeah let's get started alright guys so before we dive into code i just want to inform you about the upcoming video releases and this week my goal is to publish the second part of the video series how to create a cnn with django and react and probably at the beginning of next week i will publish the 11th part of the social network project in django so let's begin by asking ourselves what are actually signals so i think that it's much more easier to understand them on examples which we will do in this project quite a lot but basically signals in django enable communication between applications by sending some information on events that occurred and based on those events defined actions will take place so one application the sender can inform another one which will be the receiver that something has happened and that certain defined actions should be executed so with that being said let's head over to visual studio code and let's take a look at what have i done so far so basically i created four applications the buyers cars orders and sales they are empty i haven't done anything with them but in the settings py file i added them to the installed apps list and also i created a super user because we will have to login to the admin very soon because all the work will be done from there let's now go to an infomd file which represents the plan for this video so we will begin with the buyer's application here the user is going to send an information to the buyer that a user instance has been created and a buyer instance will be created based on the user and we will use a post safe signal for this then we will go to the cars application and here we will have an update of the buyer so the car will inform the buyer about something and we will do a comparison between the post safe and the pre-safe as well as pre-safe and overriding the save method and then we will head over to the orders here we will use a many too many changed on the order itself so whenever something changes in the many-to-many field we will simply do an update and then we will also do another signal between the order and the sale and we will use a post save for this and finally in the sales we will work on the sale and the order so be before the sale gets deleted we will do something to our order instance and we will use a pre-delete signal for this so now let's head over to the official django documentation because there are two approaches of registering signals which i would like to mention the first one is taking the manual connect route and the second one is using the receiver decorator and this approach will be presented in this tutorial so let's go back and let's jump into the buyers application into the models py file and over here let's create a class buyer which inherits from models.model and we will define two fields the first one is going to be the user and this is going to be a models one two one field and this is going to be a one to one field to the user we will import the user in just a second and then we will have a boolean field called from signal and this is done for educational purposes this field obviously doesn't make much sense uh we will just put in models boolean and we will set the default to be equal to false and once we will work on the cars application we will refer to this from signals so we will understand how a pre-safe signal works okay so um right now let's import the user from django contrib auth models import user and let's put it here and on delete is going to be equal models cascade cascade all right let's also add a string representation and let's return sdr self user okay so we are done with the models py file and what we can do next is to head over to the admin over here let's register this model so from dot models import buyer and now admin site register and let's put in the buyer so now we registered a buyer in the admin and we just need to go to the terminal stop the server from running and run the migration command so python manage py make migrations and python manage py migrate and python manage py run server okay so now if we refresh we have our buyers in the admin however uh we can't just yet create the buyers instances automatically so now whenever a user is created a buyer won't be created automatically and with the use of signals we will change this so whenever a user gets created a buyer instance of this user will be created as well so in order to do that we need to head over to the apps py file and this is an application configuration file with it we can configure some of the attributes of the application and we can go inside our class buyer config which inherits from app config and put in a ready method and inside this ready method we can register signals so we just need to import and then refer to the buyers applications so the first thing is that we need to put in buyers and then after the dot we need to provide the files so in this case we need to create a new one and this is going to be called signals py and now we can go back to our apps and inside the ready method we can import buyers signals so obviously we will do some work in the signals in just a second but now let's uh just set them up correctly so we are done with the apps by file i'm just going to copy the buyer's config because we will need to use this name in the init py file over here we need to set a default app config and this is just going to be the path to this buyer's config okay so it has to be as a string and we need to put in buyers and then we have apps and then this buyer's config okay so this may look scary but it actually isn't so now what we can do is to focus on the signals themselves in this application we are going to send a signal between the user and the buyer and we are going to use a post save signal for this which is probably the most popular one it triggers just after a certain model finishes executing its save method so if you've done some other tutorials on my channel you know that very often we override the save method in the models py file but if this is confusing for you we will talk about this a little more once we get to the cars application all right so enough talking let's create our first signal and we need to begin with the imports so from django db dot models dot signals we want to import our posts not pre-save but post save signal okay so this is the one thing as mentioned before we are going to uh work with the signals with the use of the receiver decorator so we need to import this decorator from django dispatch okay and then we want to grab our user because this is going to be the sender from django con con trip auth models we want to import the user and the receiver is going to be the buyer so from dot models we want to import the buyer okay and we need to begin with the receiver the first argument is the type of the signal so it's going to be the post safe and then we need to specify the sender and the sender is going to be the user because the user is going to tell the buyer hey i created an instance of the user and please create a buyer instance to this uh to this user okay so another example will be this one with the profile that i mentioned before a user is created hey create a profile to this user so the user can later i don't know add a profile picture add some bio some additional information regarding uh where the user is from what are his or hers hobbies and so on okay so we have the receiver ready and now we just need to create a function i'm just going to call it post save create buyer and this will take in the sender the sender is the user but this is not exactly what's very interesting for us what will be more interesting is the instance and the created and then we will also have keyword arguments so those two parameters are very very important because over here we have the instance of the user and the created is a boolean value which is simply equal to true or false and we can ask if created so if this user instance is created then we can write down buyer objects create and we want to set the user to be equal the instance okay so if we go to our models py file here we have a user which is a a one two one field to the user and in the signals we are setting the user to be equal to the instance so we are creating a buyer of this particular user so to understand this a little bit better let's do some prints i'm going to put in sender i'm going to put in instance okay instance and also i'm going to print the created and i forgot about closing the parentheses on the right so let me correct this mistake very quickly and inside the django administration i'm going to write down test user and i'm going to set up a password and i'm going to press press save so let's see in the terminal what happened here we have our model which is the sender then we have the instance is equal to test user and the created is equal to true okay so now if i press save again we are doing some additional work on the the user instance we can put in first name last name email address set the permissions and so on so i'm going to save it again and this time i get created is equal to false okay so after an update we have the false the true is returned only once while creation of the instance so if we go to the buyers of course here is our buyer instance this is working perfectly so we can actually add maybe another user let's call it test user 2 and i'm going to set up a password press save and let's save this again over here and go to the buyers and here is our test user too so as you can see this is working very well and yeah we can finish off with the buyers application and go to the cars application again we will begin with the models py file let's define a new class called car this inherits from models dot model and we will have four fields all together the first one will be the name it will be just the name of the car um this is going to be max length a char field with the max length of let's say 200 and then let's also put in a price and this is going to be let's make this a positive integer field okay and then we will have the buyer and this is going to be a model's foreign key to the buyer so we need to import the buyer and i'm going to do it in just a second and then we will have code is equal to models char field and this is going to be the code of this particular car let's call it a vehicle identifier number something like this but a little bit simplified and this will take in a max length of 10 and we will make this optional so blank is equal to true so now let's return to the buyer let's import the buyer from buyers dot models let's put it over here buyer and on delete will be equal to models cascade all right let's also add a string representation return and let's return the self name and then self price and the self buyer okay so now let's save this models py file let's go to the admin and let's register it so from dot models we want to import our car and admin site register car okay so let's save this let's go to the terminal python manage py make migrations python manage py migrate and python manage py run server okay let's go to home and we have our cars over here so right now what we need to do is to register signals so the question is can you try it on your own please pause the video and try to do it exactly as we did in the buyer's application okay so i'm going to do it right now i'm going to head over to our apps py file over here i'm going to put in a ready method and i'm going to import cars signals so we don't have the signals file just yet but we are going to create it right now signals py okay so in the apps py i'm just going to save it and grab this cars config and jump into the init py file where we are going to specify the default app config to be equal to and then we have to go to cars apps and then this car's config so now if we save it we have the signals set up and we just need to work on them in the signals py file so this car's application will handle at least two use cases the first one is in the models py file if we go over there we can find our code field and this code needs to be generated for each instance coming through this car class okay so we will be using a standard approach for this which i use in basically all of my tutorials and that is a safe overriding the save method but then i want to show you a alternative approach because this is a tutorial on signals and we will be using uh a pre-safe signal for the same purpose so this is the first case the second case is that if we head over to the buyers we would like to change this from signal from being false to be true okay so this is the second thing that we would like to change and yeah we will do some comparisons between if we go to the info md between uh the post safe and pre-safe and the pre-safe and the overriding of the save method so let's jump into the models py file over here i'm going to begin by overriding the save method to generate this code okay so i'm going to write down save the stakes in self and then arcs and keyword arcs and it will return super save and then arcs and keyword arcs all right we would also like to import ued to generate a random string that will be filled out over here in this code field and yeah the first thing that i'm going to do is to write a check if self code is equal to blank and in this case i'm going to set the self code to be equal u ed ued for and i'm going to wrap it up with a string and then use the replace we would like to replace this with uh nothing and we would like to bring everything to upper and then limit it to 10 chars okay so this should give us a unique code for the car let's save this and let's jump into the cars let's add a car first first car let's set the price to be 100 the buyer will be test user let's press save and continue and here is our code okay so now if i press save and continue again the code won't change because here we have if self code is equal to blank and it's only blank when we are creating this car okay so this is the traditional approach using the save method let's comment this out let's save the models py file and let's jump into signals so now we will handle this with the use of pre-saved signals so we need to import pre-safe at first from django db models signals we want to import pre save and then we need to import our receiver decorator so from django dispatch and import receiver and then from dot models import car and now we can write down receiver but in pre save and the sender will be the car itself so we aren't sending uh we aren't sending uh any information to external applications we are doing everything within the single application that is the car so you can say that the car is the sender and the car is the receiver and over here we can put in a function called for example pre save create code okay and this will take in the sender then we will have the instance but we won't have access to the created and let's put in keyword arguments for now i'm just going to write down pass because um yeah unlike the post saved signal the pre-saved signal triggers just before a certain model finish executing its save method okay so over here we don't have access to the created and let's return to our code and i'm going to actually bring everything from here not everything but the middle part from here and put it inside of this [Music] function i'm going to bring this back in and the self will be changed to instance okay because this is basically uh self is basically the instance over here and let's save this and yeah test this out so i'm going to delete this code from here all right i'm going to press save and continue editing and we have ued is not defined okay because we need to import it over here as well and let's save it refresh and i'm going to delete this one more time save and continue and here is our code so this is working as well and it's very difficult for me to tell you guys which approach is better both ways work perfectly fine as you saw just a few seconds ago i usually do it this way if i don't have to set up signals i'm not setting up signals i'm using the save method inside of the models py file if i have to set up signals so if i have to send some information to a receiver which is an external application i'm using signals the only exception is the many-to-many field which we will cover very very soon however we still need to do some work in this signals py file in the cars application and we need to bring in the buyer so from buyers dot models import buyer because as the second step we want to grab our buyer from over here okay and we want to change the field of this buyer from signal from false to be equal true so uh yeah we can do it by assigning to obj buyer objects get and we want to get it by the field that we defined um as user in the buyer so over here we have the user and this is a one two one field to the user so going back to the signals we can set the user is equal to instance and then we want to put in the buyer okay because if we look in the models we have a buyer which is a foreign key to the buyer so again in the buyer we have a user field which is a one to field one to one field to the user so we can simply write down user is equal to instance buyer dot user okay and then once we have this object we can change from signal field to be equal true and then we just need to write down obj.save okay and then we can change the name modify buyer and create code okay so now let's try this out i'm going to refresh delete this code and the test user should now have from signal is equal to true i'm going to press save and continue we have a code and if we go to the buyers test user 2 should have it false and test user should have it true okay so this is how it's working so now let's try to do the same thing with the post safe so we can actually see the difference so i'm going to copy everything from here and i'm going to comment this out i'm going to paste it over here change pre-safe to post safe we need to import post save post save okay and over here we can put in the created and yeah if instance is equal to blank we can write down instance code and we can change this um buyer to from signal to be equal from false to true and what do you think will this work so yeah let's test this out so i'm going to save the signals right now okay i'm going to change this to post save modify buyer and create code so now i'm going to save this and let's see if both of those um things will work so again i'm going to head over to the cars and over here i'm going to delete it and this time i'm going to select the test user 2 and i'm going to press save and continue so as you can see this didn't work and if we go to the buyers test user 2 is from signal is equal to true so right now both of our buyers have from signal is equal to true but this part didn't work and if we would like it to work we would need to write down instance save okay so now if we save this and we head over to the cars here we have no code and then press save and continue we have our code again so as you can see both post safe and pre-save work but i think post safe is more popular and yeah [Music] if you need to modify existing instance of a class you might consider using the save method overriding the save method this is usually what i do if i if i don't need to set up the signals okay so i think we are done with um with the signals for the cars we can now proceed to the orders so again let's jump into models py and here we will define a new class order which inherits from models dot model and over here we will have all together five fields the first one is going to be a name which is going to be a models char field with the max length of equal to 200 and then i'm going to set up a cars and this is going to be a model's many-to-many field so this is uh the most interesting field for us in this orders application in terms of using signals and here we are just going to provide the car so we need to bring it in from cars models import car so let's put it inside and then we need to have something called total so we will calculate how many uh cars do we have so this is going to be a model's positive integer field and i'm going to set blank as equal to true and then we will also have a total price and this is going to be a model's positive integer field with also blank is equal to true blank blank equals to true okay and finally we will have active and this is going to be a models boolean field which will be changed from the default value true to false once the sales object gets deleted but this is something that we will cover later so now we can add a string representation and let's return str self name and let's save it let's jump into the admin from dot models import order and then admin site register order let's save it let's go to the terminal python manage py make migrations python manage py migrate in python manage py run server okay so now we need to register signals so again we need to go to the apps py file over here let's put in a ready method which takes in a self and we want to import orders signals so again we need to create a signals file signals py and again we will leave it empty and then we are going to grab this orders config save it and jump into init py and let's write default app config is equal to orders apps and then this orders config all right so now everything should be working and we can jump into the signals py file so at the top let's begin as usual from the signals from django db models signals and from here we want to import many too many changed and then we want to import our decorator so from django dispatch import receiver and we also want to grab our order so from the models import order and now i'm going to head over to the admin take a look at our order so i'm going to add one and here is our car we will add a new one or maybe two three more in just a second here we need to provide the name of the order and the total and the total price will be based on this many-to-many field so we want to sum the total count of cars inside of this many-to-many field as well as the total price because if we head over to the cars here we have access to the price of a car and we want to sum everything and get the total resource the result for for each order okay so this is what we need to do and yeah we will use a many-to-many field for this so over here let's begin with the decorator receiver m2m changed and then here is the trick part the sender won't be the order itself it will be order and then we need to relate to the many too many fields so here we have cars order cars and then we need to put in through okay so this is the trick part for the many-to-many change and then we need to put in the name of the function m2m changed maybe something like this and let's let's call it cars order and this will take in a sender instance and also an action and then keyword arguments okay and then we can set up a variable called total and set it initially to zero and then also another one total price and also set it initially to zero so these two variables will be reflecting those two fields over here in just a second and the next thing is that we can create a for loop so for car in instance cars all and we can now increase with each iteration this total variable okay so we are increasing the total by one with each iteration and then the total price will be um extended by the car price so we can write down total price and then we can grab the car price because here we are looping through the cars and in the models py of the cars we have the price field okay so this should give us all the total cars inside the many too many field and the total price of the cars and once this is done we can assign the instance total to be equal to total as well as the instance total price to be equal to total price and we can write down instance save all right so this should do the trick let's see if if it actually works so i'm going to save it i'm going to create an order order one i'm going to select the only car available and those two fields are blank so they should be actually added automatically i'm going to press save and continue and we have not new constraint constraint fail orders order total so um what we need to do is to go to our models py file over here we are going to set null is equal to true and over here i'm going to put null is equal to true as well so now i'm going to save it and python manage py make migrations python manage py migrate and python manage py run server so let's try this out again order one save and continue and as you can see this has been calculated automatically so we have a total over here and the total price over here so let's see how this actually runs so i'm going to print print running okay i'm going to save this refresh the page save and continue let's go to the terminal nothing is over here because nothing changed in the many-to-many field this is why and let's add a car i'm going to name it car 2 the price will be 200 the buyer will be test user let's save and now i'm going to press save and continue and as you can see those fields have changed now we have two cars and the total price 300 and if we go to the terminal we have running but it's running two times so what we can do one more time is to print out but this time let's print out the action okay so let's see what is the action i'm going to save it and i'm going to get rid of one of the cars save and continue now we have only one car again we are running and we have pre and post remove okay so if we add one save and continue we are going to have pre-add and post ad so how can we um avoid duplicates we can simply go somewhere maybe over here if action is equal to post add or action is equal to [Music] post remove in this case we want to execute all the code over here and then let's just grab this and put it inside just above the for loop okay so let's save this i'm going to save this and now we have two cars um and the total of 300 and we have only one time running and one time post ad so now if i remove the car i press save and continue we have one car and the total price is 100 and here we have post remove okay so yeah this is how the many-to-many field works i'm just going to correct the name because it's here there it should be order and let's maybe add a couple of cars maybe two cars just to have uh just to be sure that this is working correctly so i'm going to add maybe awesome car and this is going to be a price of 500 and the buyer will be test user and i'm going to press save and also i'm going to add maybe a mini car and the price will be 50 the test user 2 will be the buyer save and then i'm going to select all of the cars press save and continue and now we have four cars with the total of 850. all right and here we have only running and post that okay so this is it for the many too many changed if we take a look at our info md file in the orders we covered the m2m changed and we said we also said that we want to have a post save for the order uh signal to be sent to the sale but we don't have the sale just yet so actually let's jump into the sales and into the models py and let's create this class so this is going to be a class sale inherits from models.model and over here we are going to specify two fields the order and this is going to be a models let's do this a foreign key and it will be a foreign key to the order so we actually need to import our order from orders dot models import order and let's do it on delete is equal to models cascade and also let's set the amount and the amount is going to be models positive integer field again and again we are going to provide blank is equal to true as well as null is equal to true and then let's provide also a string representation str self let's return str self amount okay i'm going to save it and register it in the admin so from dot models import sale and admin site register sale okay so now we need to jump into the terminal quit the server from running python manage py make migrations python manage py migrate and python manage py run server okay so let's jump to home to sales and let's add a sale so we have an order we have one order so we can select only the order one and we have the amount so right now what we can do is to go back to the signals in the orders and we can create another one below the many too many changed so let's write the receiver and this is going to be the post save so we need to import it post save and we also need to have our sales so let's write down from sales dot models import sale because uh the receiver is going to be the sale so here we just need to put in post save and the sender is going to be the order but the receiver is going to be the sale okay so right now what we can do is to write a function post save let's call it create or update sale and this will take in a sender instance are created and keyword arcs so here we can do it a little bit differently with the use of get or create method it unpacks two variables the first one is the object itself the second one is the created but we don't need to create it right now so i'm just going to use obj and this uh space below and sale objects get or create and we want to get it by the order and since the sender is the order we want to assign to the order the instance okay so one more time um in the sales in the models py file here we have the order which is a mo models foreign key to the order and over here in the signals we are basically referring to the sales that the order should be the instance of the sender okay so this is exactly what we have done over here and then we just want to set the obj amount to be equal instance and then total price and we just want to save the object okay so let's see how this will work i'm going to save the signals py file and i'm going to go to the orders and over here i'm going to save this save and continue so now if we jump into the sales we have our sale as you can see so again if we go to the orders and modify something over here press save go to the sales and the price is as you can see different it changed all right so um i think we are done with those the signals for the orders application and now we need to do the pre-delete for the sales application so again let's jump into the apps py let's write down ready method which takes itself and here we are going to import the sales signals so we need to create the signals py file and we will do some work in just a second over here and in the apps let's grab the sales config let's save this apps py file and jump into init default app config is going to be equal sales apps and this sales config all right so now we can go to the signals and as usual begin from the imports from django db models signals import and we want to import pre-delete pre-delete okay we need to have the dispatch decorator so from sorry not the dispatch decorator but the receiver decorator imported from django dispatch and we also need to have our sales model so from dot models import sale and also we need to refer to the order so from orders dot models import order all right let's write the decorator let's put in the type of the signal so this is going to pre-delete and the sender is going to be the sale and let's write a function pre delete change active order and this will take in a sender instance and also keyword arcs so over here we can assign to obj instance order because the sale is the sender so we have an instance of the sale and in the models py we have an order here over here order field over here which is a foreign key to the order so basically we are getting the order by writing instance dot order okay so now in the obj we have an order and if we have this particular order we can simply change the active to be equal to false alright and we just write down obj.save so again here we have the order this is a foreign key to the order and we are talking about the instance of a sale so we are assigning uh to the obj variable this particular order stored over here and if we have this particular order we can access this active field and change it from default true to false and this is exactly what we are doing over here so once we take the sale and delete it the order should be no longer active and i'm going to save this head over to the orders here is our order one it's active right now and if i go to the sales and delete it let's go to the orders the order is no longer active okay guys so i think we can finish off over here this was a this was a quite a long one i hope this tutorial was helpful for you to understand the basics of signals and yeah see you in the next video take care have a great day and bye bye
Info
Channel: Pyplane
Views: 10,190
Rating: undefined out of 5
Keywords: django signals, signals, signals in django, django signals for beginners, post_save, pre_save, m2m_changed, pre_delete, learn django signals, django signals tutorial, django signals post_save, learn django, django signals pre_save, django signals explained, django signals example, django signal post save
Id: W8MLlwvSS-U
Channel Id: undefined
Length: 54min 32sec (3272 seconds)
Published: Fri Jul 31 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.