ErezO
ErezO

Reputation: 364

How to split django apps if shared view

There is a common case I encounter, where I can't find a way to split apps.

The case is when a info of two models is related and needs to be in the same template

An example speaks 1000 words: (2 models - pages + comments).

# models.py
class Page(models.Model):
title = models.CharField()
content = models.TextField()  


class Comment(models.Model):
page = models.ForeignKey('Page')
content = models.TextField()


# url.py
...
url(r'^page/(?P<page_pk>\d+)/$', views.ViewPage, name='page-view-no-comments'),
url(r'^comment/(?P<comment_pk>\d+)/$', views.ViewComment, name='comment-view'),
url(r'^page-with-comments/(?P<page_pk>\d+)/$', views.ViewPageWithComments, name='page-view-with-comments'),
...


# views.py
def ViewPage(request, page_pk):
page = get_object_or_404(Page, pk=page_pk)
return render(request, 'view_page.html', {'page':page,})


def ViewComment(request, comment_pk):
comment = get_object_or_404(Comment, pk=comment_pk)
return render(request, 'view_comment.html', {'comment':comment})

def ViewPageWithComments(request, page_pk):
page = get_object_or_404(Page, pk=page_pk)
page_comments = Comment.objects.filter(page=page)
return render(request, 'view_page.html', {'page':page,'page_comments':page_comments'})

In this situation, splitting to Page app and Comment app is problematic, because they share a view (ViewPageWithComments) and url.

My options are:

1) Create an Ajax call to comments, which has crawling problems although Google might have fixed it lately.

2) Create a method of page that calls a method in the comments app that returns html with the comments content. If the method needs more arguments I also need to write a custom filter tag.

3) Decide not to split...

Am I missing something and there's another option? When would you prefer (1) vs (2) ?

Note - I created a very simple example to keep the problem general.

Upvotes: 0

Views: 289

Answers (1)

Sayse
Sayse

Reputation: 43320

You don't need to split anything, you have the pages, and comments have a foreign key to that so you can just iterate over the pages comments

{% for page in pages %}
    {% for comment in page.comment_set.all %}
    {% endfor}
{% endfor %}

If you want to be able to use the same template for a version of this page without comments you can just wrap the comment for loop in an {% if show_comments %} statement

Upvotes: 1

Related Questions