Hello and welcome to another walk through for Django for Everybody. In this walk through we're going to take a look at the sample code called well. The name well is based on a long time early pre-internet forum in Berkeley, California, and so you can go look up the well. So the basic idea of the well is it looks exactly like myarts, it's pretty much a clone of myarts. So if you recall myarts, you had articles crud, article, article, submit, article crud, delete, just to basically article crud, right. So the only difference between this and the well is there's a search box here. So I can search for things that have yacht in them, and then I can clear the search box. And that's it. So first, let's observe something that we can observe from the outside when I do a search. The search is a get parameter, and the reason for that is that we want this, get parameters are get URLs or item potent. So that basically says go to my blog and find all the blog posts that mention one, two, three. So I could, right, I could put that in as, let me clear my search here, and I could do, let's search for DSS, [LAUGH] DSS search here. So this URL is the search for the ones that are DSS. So now I've bookmarked both these, and now that is going to be a short link to the ones that say DSS. So what I'm going to do is clear the search now, and this will show you something about item potent URLs. I'm going to say, Yada 456, I was here, Submit. So now I have two that have the word Yada in the title. Watch what happens when I go to the URL that I bookmark. So I see now two posts. So the key of item potent is not that you get the exact same page, you get the exact same logical page. Not the exact same text every time, it's not like a cache that just clones the text. I go to this before and then I go to it now, and if I then delete this one and then I go to this again, that's the ones that have Yada in them. And so that's why we're going to do a search for Yada. And it's really quite simple here, I'll show you everything but let's just start with an inspect element so you can see what's going on here. The first little trick here is you can construct that URL, and this goes way back. This goes way back to a form without a method equals post, which means it's a get method which means that this name equals search becomes, it just goes on and it does a get request. So instead of doing a post request, which we've been doing for weeks now, this does a get request and it adds a get parameter. Okay, and so we've got in our view, our main view, that is well, we're seeing a get parameter. It is not a different view. We're getting a view with a get parameter, and that also means that if I inspect element on this little undo icon that I made, inspect. All I'm doing is I'm making a link to slash well without the parameter, so it's super easy. So get rid of the search is just go to a different URL. I could have done it, well is an anchor tag, it's an href tag, look, so I've just gone to well and it's not there, it's the same view, so searching. And if you were to go and take a look at how Amazon or Google, they do search, they are forever putting that stuff in the URL so that you can then bookmark them. So I'll get rid of those bookmarks later. But you see how that is idet potent. That's, when I said weeks ago, I said get URLs are item potent. I can now sort of show you in code that we're writing how that works. Okay, so let's take a look at our code. I'll clear my search here. The code here is pretty straightforward. We've got a really simple model. It was pretty much taken straight from the myarts code. This is like a, it's got a name. I called a post instead of articles because I've got all these applications running at the same time so I have to change a few names here. Related name is when we're putting a lot of foreign keys into owner across my Django project. So you gotta be careful to choose a name for related names so you don't end up with a collision. You can't just say owner or whatever. So I call this post owner so that you don't back in the owner model, back in this model right here, the auth user model, we're pushing in effect methods or attributes into that model, and so we gotta name them. And so this related name is really quite important to make sure across all of my applications. And what I mean is by all, these are all applications in one giant Django project. So this name here wants to be, and lots of these applications are using owner. And they're making a foreign key in the auth model, which is perfectly okay, it's just you gotta be careful about the related thing. So that's why that's there. So let's take a look at the URLs .py. The main URL that we're going to change is this one, right, it's the list view. And here it is in the list view, and I don't know which way to go first here. Let's let's compare and contrast this list view with the views in myarts. So in myarts the list view, I could just borrow owner list view which was extended generic list view, and I just say my models article and it was good. But now I gotta do a whole bunch more work here. So I actually am going to, and I might have been able to do this by sort of overriding a few methods like we have done in the past, but I just decided that I would simply write all the code. And so I'm just extending view here. So I'm only extending view to make post list view. I'm still following the pattern so I can say what the model is. I'm not sure I even use that. Let's see if I can use model. I don't even need that. Simply I'm using that. It's kind of, yeah, so I'm using the template name here. So I still am going to use the template name, but I didn't need the model because I am, the reason I didn't need the model as I'm just explicitly using post in all the places. And so just get that so it's not, I mean I don't like code that does nothing, it's always a mistake. Okay, so the get request, most of this is in a get request. There is no post here because in the list view, the list view which is this view, there is no post. This form is a get request, that's a get request. And all it does is we are going to do a get request, and we're going to do two versions of that get request. We're going to have one version to the get requests based on whether there's a search get parameter or not. So we're basically saying go grab a get parameter, put the get parameter using the get method of a dictionary. Big uppercase GET is the dictionary and lowercase get is the name of the method in Python, search is the key and then default is false. If we get a string then we've got a search and filter, but let's start with this. All we're doing here is we're grabbing the objects and this is the kind of code that is done automatically and owner list view which is then generic list view, right? So this is just I'm just doing the code. Now the thing I get to do with this that's really nice is I can go through and augment this object list. So this is a list of objects and I'm going to change each object and I'm going to add a field, I'm just undo, undo, undo, I don't know all I just did. Undo, undo, undo, that I want. So this is an object. So objects is a list of objects and I'm going to grab it and I'm going to add a field so sort of in the middle you can add this natural- updated and I'm going to base it on updated at which is the long ugly looking date. It's a real date, but it's a long ugly looking date and I'm going to run that through the natural time filter, which again is something built into Django that puts in this 15 hours ago thing, which is much nicer than just putting the data. Okay, and so we're going to send the objects in this post list, which is the list of objects and then we're going to send the string, the search value in just so we can show that, yes, so that when we want to see this Yada so you can actually change this, right. So we want to put this back in, right? So we're going to pass that into the template and then we're going to render the template, dump queries as code just to show the queries that are actually being run if I was running this locally. So let's take a look at the code. So for most of this, literally, it's the same thing. Okay, so it's basically looping through, its doing a little bit more tricky stuff here. If a text is less than 100. I'm putting it all in and in the list I'm only going to put, so put the post, the length is less than 100, slice is 0.99. Let's see that, Guess because I'm not the owner. That's because I'm not the owner hosted by dj4e-samples. Who am I in this situation? Let's add a post, quite a title, Zap. One, two three, Submit. Yeah, so it's showing this detail that that's what I was confused about, see this little detail which now would that end if that post text length greater than 100, so there's actually a bug in this code right here. And since I'm running it on samples, it will take me a while to get updated but I'll just point out that there's a bug here and I'm going to fix it because I really miss this if post owner ID. That's our standard like to show the edit and delete, and I inadvertently had this code that showing the actual text. This is what I wanted to look like. I wanted a title and I wanted a short summary. So you have to go into here to get the whole summary but the short summary of the text. So this code when you run it again, you will see after I update all this and push it through GitHub and run it in production, I will fix this, okay. And so, that is what makes this to keep that nice and short, 99 might be too long of thing. I'd rather that stuck to one line, but whatever. Posted by the username in this case, there's the username, that's nice. And a URL into the post detail. So this is really straightforward stuff other than that little cool bit there putting the summary in. But the only thing we really bad at here is this form and we are going to do a form, because we haven't said action equals on the form tag. It is going to post right back to the same URL that it came to, I mean not post is going to do a get because there's no method equals post here. It is going to get right back to this same URL and I have the input with the placeholder, the placeholder is what gives me this little searchy bit thing, see that it's not really the string search. It's a placeholder if it's empty, and then I have value equals. No, I'm do value equals search here. Which is taking the old search value. Old search value, zap was there, and so that that's putting zap back in there. And of course it's escaping it and so if we were, HTML entities problem here, whatever. And I put this in a if, right, and that you don't have to put these on separate lines. You see me doing a lot of that where I'm having the if and if on separate lines, but here I just have it like right in the middle of a line and that just is going to admit that text in the middle of that line. I'm using a font awesome icon for the search so that I get this little search button. That's kind of cute. That's a thing called font, awesome. You can go look that up, and then I have a link that goes back to well:all I could probably call this like quest.path or something because it's really would be the same thing instead of URL. Well:all I could just go back to the request path which would be slash, what, slash, but it doesn't matter, well: all is nice and then I throw another font. Awesome in there which gives me a little undo thing and we've been using these little font awesome creatures for a while now. And so that's really all that is needed to get this new bit of user interface into the output, in so really the only thing left to show you is the code where it handles the search. So there is a filter. So host objects all order by. That's what happens if it's not searching. So what you see here is all we've done is instead of saying all, we say filter. And there's a couple of ways you can do filters, you can do like just if you're doing one field. This is a really funky syntax that uses two underscores, title is a field in models.py, right. Title is a field in models.py, double underscore contains that is like an operator, and then this is a string value which is just a string here in our python code. Now I want to actually search through both the title and the text. So I'm going to have to make myself a combined search. So I'm going to make a query and I'm going to use this db models two which means allow, I can create a query in and I could do it in a really long yucky query there, but I'm going to start with a query that says the title contains the string and then I'm going to add to that an or claws. We're stuck in Python, right? It's not SQL. We're stuck in Python. So we got to have this funky thing. So this says these two things create a thing that basically says if the title contains that string whatever it was zapped so contains that string or if the text contains that string. Select it and now instead of all I put filter query so I pull the query in and then select related. This is an efficiency thing that says look I'm going to actually look at all the data, so run that whole filter, run the username, do a bunch of stuff. So I got a comment toward the bottom of this that talks about select related. And then the order by and then showing just the first ten. That's the same and there we go. And then we augment that and then away we go. So search is either in this case search is either the get request from the former get is that value in this particular instance. Or it is false and then that triggers of course this bot of code in the template so that's pretty much it. I mean, I certainly probably over talked it. It's not that complex. So I want to show you only one more thing for this before we wrap it up and that is a new pattern. So you'll notice if you look in here there is only one view. There is just the post list view. And if we take a look at articles, we've got these views the detail view, the create view, the update view and the delete view. And they all extend owner create view and then just change these variables. I over wrote this list view because I had a whole bunch of other things I wanted to do that ownerless view wasn't going to do for me, right? And so what you'll notice that in the well, I don't have those. So let me show you how these and you'll notice I have edit views right? I got them. They're still there and there are templates. CD templates, well, the templates are there. Okay, and as a matter of fact in this one, I changed the default name of the templates because I'm kind of tired of putting underscores in front of certain things. But let me show you how I solve the problem of where are the views? They're actually fully in URLs at P1. So here is so I import owner list view, owner detail view, owner create view and owner update view. And so what I'm saying is map the post/intPK which of course is the detail file right? post/intPK and I would like you to call owner detail view, which is a class that's come from my arts.owner as view and then you can put a series of key value pairs in that override the default values of same model and template name. And so I'm saying models equals models.post. I know that. That's the name of my model, right? And then template name equals and now I'm even saving taking the app name which happens to be sitting conveniently in a string here and concatenating it to detail slash HTML. And so that is the view and of course name equals is just part of the URLs thing. And you'll notice that when I do the create view I set the success URL the model, the template and now I'm remember I want to hide some of the fields. I want to show which fields are there and which fields aren't right? And so if we look at this views you see like which fields you actually want to show because I don't want to show the created add etc., and updated at right in the models. I don't want to put owner out. I don't want to put created add out. So I'm going to give a list. I'm going to give a list. Come back. I want to give a list of the fields I want to show on my create form. So again, these are sort of class-wide variables that turn into object instance variables when it makes this view and it overrides all these things. And so all the stuff that I was doing interviews.py I am now doing in ursl.py and just reusing owner create view. And you see an update delete. They're all kind of there, right? And so I don't actually need to put the views in. And this is really it looks a little more complex, but I think it's a lot prettier than putting these silly views in over and over. So that's a pattern that you may want to use. It made it easier for me to rename from well to something something else if I wanted to because really well is only hard-coded one place in here, so that's kind of cool. Okay, so there's a couple of lessons here, you know one is this searching? One of the search and how that works. But then also a new way to create views that never really leave urls.py. And remember we I built this owner detail view to meet my needs. So things like template view, that's something that isn't just a bunch of code somebody wrote. So, okay. Well, I hope this walkthrough of the well sample application has been useful to you. Cheers.