create a django-queryset with all objects but not all related many to many fields by a condition

Question:

class Post(models.Model):
    text = models.TextField()


class Project(models.Model):
    name = models.CharField(max_length=60)
    description = models.CharField(max_length=500)

class Tag(models.Model):
    name = models.CharField(max_length=60)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)


class TaggedPost(models.Model):
    org_post = models.ForeignKey(Post, on_delete=models.CASCADE)
    tags = models.ManyToManyField(Tag)

Assumed I have defined above models.
There exist multiple projects which all have multiple tags.

Eg:

  • Project1 -> Tag1, Tag2
  • Project2 -> Tag3

Not every Post do have a TaggedPost object.
Eg.

  • Post1 -> no tags
  • Post2 ->TaggedPost -> Tag1
  • Post3 ->TaggedPost -> Tag2
  • Post4 ->TaggedPost -> Tag2, Tag3 (Here are tags of multiple Projects)

What I now want to do is a queryset which contains all Posts (also the untagged posts) but only tags of a defined project.

qs.include_tags_of_project(Project1) results in:

  • Post1 -> no tags
  • Post2 -> Tag1
  • Post3 -> Tag2
  • Post4 -> Tag2

qs.include_tags_of_project(Project2) results in:

  • Post1 -> no tags
  • Post2 -> no tags
  • Post3 -> no tags
  • Post4 -> Tag3

any sugestions how to handle that?
Thx

Asked By: Schulzjo

||

Answers:

At first, get all posts by project.id (or project.name or description)
At second, made prefetch_related, to get all tags for project. Prefetch help you get only tags for especially project.

Post.objects.filter(taggedposts__tags__project_id=project1.pk).prefetch_related(Prefetch('tags', queryset= Tag.objects.filter(project_id=project1.pk)))
Answered By: Maxim Danilov