Reputation: 364
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
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