2

Django newbie here...

I have three models which I'm currently wrestling with and I obtained a desired solution. However, the solution is certainly not efficient nor good practice. I just don't know enough to adequately implement what I want.

Here are the models...

basics/models.py

class Tag(models.Model):
    slug = models.SlugField(max_length=200, unique=True)

    def __unicode__(self):
        return self.slug
    def get_absolute_url(self):
        return reverse("tag_index", kwargs={"slug": self.slug})


class post(models.Model):
    title = models.CharField(max_length = 180)
    // a bunch of other fields here
    tags = models.ManyToManyField(Tag)

    def get_absolute_url(self):
        return reverse("post_detail", kwargs={"slug": self.slug})

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = "Blog Post"
        verbose_name_plural = "Blog Posts"
        ordering = ["-created"]

projects/models.py

class project(models.Model):
    projectTitle = models.CharField(max_length=150, null=False)
    projectTag = models.OneToOneField(Tag, primary_key=True)
    description = MarkdownField()

    def __unicode__(self):              # __unicode__ on Python 2
        return self.projectTitle

    class Meta:
        verbose_name = "Project"
        verbose_name_plural = "Projects"

Now... what I would like to do is to create an adequate view, which passes to my template only the posts which are tagged with the project tags rather than all posts as it is currently doing.

projects/views.py

class projectFeed(generic.ListView):
    queryset = project.objects.all()
    template_name = "projects.html"
    paginate_by = 5

    def get_context_data(self, **kwargs):
        context = super(projectFeed, self).get_context_data(**kwargs)
        # slug = self.kwargs['projectTag']
        # tag = Tag.objects.get(slug=slug)
        context['posts'] = post.objects.all()#filter(tags=tag)
        return context

As you can see, I tried some stuff that I used for creating the view for displaying all posts with a certain tag but I couldn't get it to work here.

projects/templates/projects.html

{% for project in project_list %}

<div class='postContent'>
    <!-- project stuff here -->

    {% for post in posts %}
        {% if project.projectTag in post.tags.all %}
            <p><a href="{% url 'post_detail' slug=post.slug %}"> {{ post.title }} </a></p>
        {% endif %}
    {% endfor %}


</div> 

{% endfor %}

Ideally... I want to pass a nested list of sorts where each project in the project_list has an associated list of posts which I can iterate over in the inner for loop without needing to check the tags. That is, I want to filter and arrange the data in the view method/class OR another more efficient place.

1 Answer 1

1

You can get list of related post using next relate managers: posts = project.projectTag.post_set.all() Why won't you try using it in your template

{% for project in project_list %}
<!-- project stuff hete -->
   {% for post in project.projectTag.post_set.all %}
   <!-- post stuff goes here -->
   {% endfor %}
{% endfor %}

But to reduce number of sql queries you will have to override get_queryset method of your ListFilter:

def get_queryset(self):
    return super(projectFeed, self).get_queryset()
                          .select_related('projecttag')
                          .prefetch_related('projecttag__post_set')
Sign up to request clarification or add additional context in comments.

3 Comments

Great, that works... could you explain the mechanics behind this a little? More specifically, these methods .select_related('projecttag').prefetch_related('projecttag__post_set') and what exactly this argument does projecttag__post_set
@Constantine well, it won't definitely be a short answer. Won't you mind if I update my answer with more details later? And meanwhile you can read about select_related and prefetch_related in django documentation docs.djangoproject.com/en/1.8/ref/models/querysets/… docs.djangoproject.com/en/1.8/ref/models/querysets/…
Yes feel free to update the answer. However, despite reading the documentation, I don't know how to limit the returned number of posts per project from within the get_queryset function rather than a counter in the template. Could you please elaborate in this direction?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.