Django.fun

Django cant figure out how to use foreign key

'''

class Project_types(models.Model):
    project_type = models.CharField(max_length=200)

    def __str__(self):
        return self.project_type

class Projects(models.Model):
    project_types = models.ForeignKey(Project_types, on_delete=models.CASCADE)
    project = models.CharField(max_length=200)

    def __str__(self):
        return self.project

'''

When I try to run - Project_types(project_type='games').item_set.all() I get an error saying that there is no attribute item set.

Answers: 3

Answered by Phan, Oct. 13, 2021, 3:15 a.m.

Project_types(project_type='games') doesn't actually return any object. That's why you got that attribute error. You need to add a filter or use get. Something like below:

Project_types.objects.get(project_type='games').item_set.all()

Or

Project_types.objects.filter(project_type='games').item_set.all()
Answered by Reed Jones, Oct. 13, 2021, 3:16 a.m.
class Project_types(models.Model):
    project_type = models.CharField(max_length=200)

    def __str__(self):
        return self.project_type

class Projects(models.Model):
    project_types = models.ForeignKey(Project_types, on_delete=models.CASCADE)
    project = models.CharField(max_length=200)

    def __str__(self):
        return self.project

First there's a few problems with your model.

First model names shouldn't be pluralized

Here a Projects (should be Project) has one project_type, and a Project_types (should be ProjectType) has one project.

To run the query you want:

Project_types.filter(project_type='games').item_set.all()

the correct query would be:

Project_types.filter(project_type='games').projects_set.all()

use projects instead of items,

the related manager is based on the Model name (in this case Projects becomes projects_set)

see here https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/

Answered by Steffo, Oct. 13, 2021, 3:16 a.m.

The .item_set attribute does not exist on the instance you have created by running:

Project_types(project_type='games')

It seems to me that you are trying to get all Projects of the type 'games'.

To do that, you'll have to use the QuerySet of the Projects class like this:

Projects.objects.filter(project_types__project_type='games').all()

Additionally, a suggestion: try to name all your model classes using singular CamelCase, so that they will be easier to understand. In your example, Project_types should be ProjectType, while Projects should be Project.