Brought to You by the Letter F6:59 with Kenneth Love
Django's `F()` objects are a little weird to get your head around sometimes, but they very useful when you need access to values in the database in real time.
Check out the
F() objects documentation.
F objects are really handy when doing annotations and aggregations, which we'll get to in a couple of videos.
[MUSIC] 0:00 Django's F objects are a little weird to get your head around sometimes. 0:04 But they're very useful when you have access to values in the database in 0:08 real time. 0:11 Django's ORM has a useful feature known as F objects or F expressions. 0:13 These objects let us refer to the value of a field as it currently is 0:17 in the database, 0:20 instead of how it is an instance which could very well be outdated. 0:21 Let's hop into Workspaces to see a bit more about them. 0:25 Before we do F or Q objects in our next video, I wanna go and update the quiz 0:28 model so that it tracks the number of times that the quiz has been taken. 0:34 So if we were doing this for a real app, something that's gonna go live on 0:38 the Internet, we would want a solution for this that actually uses users. 0:43 So like we'd have another table that's the quiz and the user and 0:49 how many times was this thing taken. 0:53 We'd add a new record, things like that. 0:56 We're not gonna worry about that for now, though because we wanna do this as a, 0:58 you know, example. 1:03 And just a way to test our ideas, 1:04 because we might come up with ideas that don't work. 1:06 So we need to test these before, and then we'll find out later. 1:10 So cool, all right, so I'm gonna say times_taken. 1:14 And that's models.IntegerField and 1:18 a default=0 because by default no quiz has been taken. 1:21 And I'm gonna mark this as not editable cuz it shouldn't show up in the Admin. 1:25 We just don't care. 1:29 All right, come down here and click that, 1:32 managed.py makemigrations courses. 1:37 And manage.py migrate courses. 1:43 All right, so our model has a new field. 1:49 It's not gonna show up in the Admin or model forms. 1:53 So that's why you've marked it non-editable, which chicken and 1:56 egg thing right there. 1:59 We've given it a default. 2:01 Because we want them all to be taken zero times. 2:03 Also we don't have a way to actually take quizzes. 2:06 So we're gonna ignore that [LAUGH] though. 2:08 And we're just going to pretend that this thing is happening. 2:10 All right, so we're tracking the statistic and 2:13 we're putting it into a database field. 2:15 Whether or not it should go into a database field is a question for 2:17 another time. 2:20 All right, so let's go into our shell. 2:22 And from courses.models import Course and 2:27 from django.db.models import F. 2:32 All right, so F objects let us get to our model fields directly in the database. 2:37 Instead of having to grab an instance and 2:42 then use whatever value we get at that time. 2:44 Database values can change instantly from multiple inputs and 2:47 views and just all sorts of stuff. 2:51 So we don't want to rely on whatever the value is 2:53 in an instance when we're doing certain things. 2:57 So I mean, for example, if we were going to update the number of times that a quiz 3:00 have been taken, we might do something like this. 3:03 We might do like quiz = Quiz.objects latest. 3:05 Wait, I need to import Quiz. 3:14 And then by id, cool. 3:20 All right, so I have a quiz. 3:24 And I might do times_taken += 1 and quiz.save. 3:26 And okay, cool, if I check quiz.times_taken. 3:34 Let me actually clear this real quick. 3:40 All right, quiz.times_taken. 3:41 I get out a 1. 3:44 So cool, okay, that seems to work, right? 3:45 Okay, but now what if we pulled this out and it was zero and 3:49 then someone updated it before we called save? 3:53 We're telling Django to save it with one as the times taken. 3:56 To increment it to one from whatever it was in the instance. 4:00 But it should be like two or three or four, right? 4:03 Our instance started as at zero. 4:09 When we did the plus equals one it becomes one. 4:11 And if it was saved by somebody else before then, we're still saving it with 4:14 one, when really it should've gone to two or three or four or whatever. 4:17 Our data's wrong. 4:21 That's bad, but this is where F objects come in and save everything. 4:23 So let's do quiz.times_taken 4:29 = F('times_taken') + 1. 4:35 And then we do a quiz.save. 4:40 If we look at times taken, then it's this combined expression which is kinda cool. 4:45 But it's also kinda weird cuz we haven't seen this before, right? 4:51 We haven't seen this before. 4:54 It's this combined expression and it's a way for 4:54 Django to know what's supposed to be going on there. 4:56 What we have to do is we have to update our quiz from the database. 4:59 So we'll do quiz.refresh_from_db, and 5:02 then if we look at quiz.times_taken, we get 2. 5:06 Just as we would expect. 5:10 We can actually make this F object even more succinct 5:12 by doing it in an update instead of requiring two queries. 5:15 A get and a save. 5:19 Let's pretend that all of our quizzes have been taken at least once. 5:21 So we'll do quizzes = Quiz.objects.filter. 5:25 times_taken is greater than or equal to 2. 5:31 Let's just do all of them. 5:38 Let's just do all of them. 5:40 All right .all. 5:42 And I want to do an update on this. 5:44 I want the time taken= 5:46 F times taken+1. 5:51 Cool, so if I now update my quiz, 5:56 cuz if I look at quiz.times taken, I still get 2. 6:00 Let's update it from the database. 6:06 Refresh_from_db, because this is a frozen instance, right? 6:09 This thing just exists in memory. 6:15 It's gonna stay here. 6:16 It doesn't change automatically. 6:17 So now if I look at times taken, I should get 3. 6:19 And there it is. 6:22 So that's awesome. 6:23 It's the correct value, just what we wanted. 6:24 And we can see how the F objects work better by going to the database for 6:27 this kinda stuff. 6:31 You wanna really use this on things like this 6:33 where it's going to be sensitive data. 6:36 It has to be up to date and correct. 6:38 You may not find yourself using F objects very often. 6:42 But F objects are very handy for reducing the number of queries you have to do and 6:44 avoiding race conditions in your code. 6:48 We'll have some more uses for F objects in a bit but first, we'll look at a slightly 6:49 more common ORM tool for bringing some more advanced logic into your lookups. 6:54
You need to sign up for Treehouse in order to download course files.Sign up