title: My Third "Grab Object in Django" Post
body: <p>Clearly I am struggling with various permutations of grabbing objects in Django. Here's another.</p>
  
  <p>This is for the same library app I've been working on (in case you have seen my other questions). </p>
  
  <p>On the home page, I display the active user's name and information (this works fine). Then I wish to display all of the reviews that the active user has written. I am basically able to do this as well, except it just shows the reviews with no reference to the books they are supposed to describe. </p>
  
  <p>So... I need to be able to grab the Book object by its Review object. In other words, each time I display a Review, I want to be able to grab the Book (title and author) that it pertains to. Keep in mind that I can't grab the Book by the User (using created_by), because a user can write reviews for books that they did not add to the db. I hope this makes sense but I'm sure you can see that I am struggling with such problems.</p>
  
  <p>In models.py, I set up my tables like this (keep in mind that the User table is in a different app):</p>
  
  <pre><code>class Book(models.Model):
      title = models.CharField(max_length=100)
  
      author = models.ForeignKey("Author", on_delete=models.CASCADE, related_name="books")
  
      created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="books_added")
      created_at = models.DateTimeField(auto_now_add=True)
      updated_at = models.DateTimeField(auto_now=True)
  
      objects = BookManager()
  
  class Author(models.Model):
      first_name = models.CharField(max_length=100)
      last_name = models.CharField(max_length=100)
  
      created_at = models.DateTimeField(auto_now_add=True)
      updated_at = models.DateTimeField(auto_now=True)
  
      objects = AuthorManager()
  
  class Review(models.Model):
      rating = models.IntegerField()
      comments = models.TextField()
  
      book = models.ForeignKey("Book", on_delete=models.CASCADE, related_name="reviews")
  
      created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="reviews_added")
      created_at = models.DateTimeField(auto_now_add=True)
      updated_at = models.DateTimeField(auto_now=True)
  
      objects = ReviewManager()
  </code></pre>
  
  <p>Then in views.py I am trying to define a variable "book" by referencing the Review object (since book is a field within review). Like so:</p>
  
  <pre><code>def books_home(request):
      if request.method == "GET":
          first_name = User.objects.get(id=request.session['uid']).first_name
          last_name = User.objects.get(id=request.session['uid']).last_name
          email = User.objects.get(id=request.session['uid']).email
          user_id = User.objects.get(id=request.session['uid']).id
          reviews = Review.objects.filter(created_by=user_id)
          book = Review.objects.filter(created_by=user_id).book
          context = {
              'first_name' : first_name, 
              'email' : email,
              'last_name' : last_name,
              'reviews' : reviews,
              'book' : book
              }
          return render(request, 'html_files/home.html', context=context)
  </code></pre>
  
  <p>Keep in mind that essentially everything in here works except <code>book = Review.objects.filter(created_by=user_id).book' and</code>'book' : book` in the context dict. </p>
  
  <p>Also keep in mind that I am very new to Django and to programming in general. I'm sure there are more elegant ways to do this, but I am sticking to methods that I understand, so in answering, please try to stick as close to my current code as possible. "Make it work, then make it work better."</p>
  
  <p>I believe I know what to do in the template to show the context dict, so that is not a problem. The code is on GitHub if that would help.</p>
  
  <p>Thank you.</p>