Simple reverse relation lookup

Hi everyone, I have a 2 questions about reverse lookups in django and I am trying to see the sales that a restaurant gets. I am beginner to django and trying to learn reverse lookups using the related_name field.

I am trying to learn ORM from a video on youtube and pretty much just copied everything, which went fine for the teacher. https://www.youtube.com/watch?v=46au1MxtOJE&t=1881s. (@27ish minute mark)

(1st question) When I run this code and get an attribute error of : WHY?

AttributeError: ‘Sale’ object has no attribute ‘name’

    restaurant = Restaurant.objects.first()
    print(restaurant.sales.all())

(2nd question) Using the managers associated with ForeignKeys like FOO_set I get this error using this code: WHY?

AttributeError: ‘Restaurant’ object has no attribute ‘sale_set’

 restaurant = Restaurant.objects.first()
 print(restaurant.sale_set.all())

Below is the code for the model I am using:

class Restaurant(models.Model):
class TypeChoices(models.TextChoices):
    INDIAN = 'IN', 'Indian'
    CHINESE = 'CH', 'Chinese'
    ITALIAN = 'IT', 'Italian'
    KOREAN = 'KR', 'Korean'
    MEXICAN = 'ME', 'Mexican'
    OTHER = 'OT', 'Other'

    name = models.CharField(max_length=100)
    website = models.URLField(default='')
    date_opened = models.DateField()
    latitude = models.FloatField()
    longitude = models.FloatField()
    restaurant_type = models.CharField(max_length=2, choices=TypeChoices.choices)


class Sale(models.Model):
     restaurant = models.ForeignKey(Restaurant, on_delete=models.SET_NULL,null=True, related_name='sales')
     income = models.DecimalField(max_digits=8, decimal_places=2)
     datetime = models.DateTimeField()

Thank you

On making queries:

You can override the FOO_set name by setting the related_name parameter in the ForeignKey definition.

So the answer to question 2 is that you provided related_name: you get either the related_name or the FOO_set, not both.

Question 1: name is a field on your restaurant model, not your sale model. Use .restaurant to get back to the restaurant from the sale.

~happy coding!~

Thank you for the help understanding FOO_set! On the above video the guy put this:

restaurant = Restaurant.objects.first()
print(restaurant.sales.all())

And it returned the sales data with no problem. I don’t understand why mine is giving that error?

Which error is it giving you?

For this and for future reference, whenever you are requesting assistance with an error, please post the complete error message with the traceback as it appears in the server console. (Do not post screen images of any errors being reporting in the browser page.)

Here is the traceback, Thank you.

Traceback (most recent call last):
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/manage.py", line 22, in <module>
    main()
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django_extensions/management/email_notifications.py", line 69, in run_from_argv
    super().run_from_argv(argv)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django_extensions/management/email_notifications.py", line 81, in execute
    super().execute(*args, **options)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django_extensions/management/utils.py", line 65, in inner
    ret = func(self, *args, **kwargs)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django_extensions/management/commands/runscript.py", line 332, in handle
    run_script(script_mod, *script_args)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django_extensions/management/commands/runscript.py", line 189, in run_script
    exit_code = mod.run(*script_args)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/core/scripts/orm_script.py", line 9, in run
    print(restaurant.sales.all())
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/db/models/query.py", line 377, in __repr__
    return "<%s %r>" % (self.__class__.__name__, data)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/venv/lib/python3.9/site-packages/django/db/models/base.py", line 588, in __repr__
    return "<%s: %s>" % (self.__class__.__name__, self)
  File "/Users/sniperfox/Projects/Programming/WebDesign/Database Practice/core/models.py", line 42, in __str__
    return self.name
AttributeError: 'Sale' object has no attribute 'name'

If you focus on the last element that refers to your code (and not Django or Python library code), that becomes your first place to look.

So, in this case it’s:

What you want to look at now is the model that contains an __str__ method at line 42 in your core/models.py file.

What is the code at that location? (Please post the complete model.)