Reputation: 383
I have been creating a Hackernews type clone recently and bumped into some trouble with my database layout and views.
Basically, a user can post a story and choose only one category for each story. Here are my models:
models.py
class Category(models.Model):
category_name = models.CharField(max_length = 50)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return self.category_name
class Meta:
verbose_name_plural = "categories"
class Story(models.Model):
title = models.CharField(max_length = 200)
url = models.URLField()
points = models.IntegerField(default = 1)
moderator = models.ForeignKey(User, related_name = 'moderated_stories')
category = models.ForeignKey(Category, related_name = 'categories')
voters = models.ManyToManyField(User, related_name = 'liked_stories')
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
@property
def domain(self):
return urlparse(self.url).netloc
def __unicode__(self):
return self.title
class Meta:
verbose_name_plural = "stories"
Firstly, I would just like to confirm that this is the way it should be layed out?
This then leads onto my second problem. I want to collect all the stories that belong to a particular Category and display them at their respective urls (i.e. localhost/engineering would show all the stories within the engineering category).
Here is my view/urls so far. All it does is assign each category in the database its own url.
url.py
url(r'^(?P<category_id>[0-9]+)/$', 'stories.views.category'),
views.py
def category(request, category_id=1):
template = 'stories/category.html'
category = Category.objects.get(id = category_id)
return render_to_response(template, {
'category': category
})
What could I add to my Category view such that I collect all the stories with the same category to display within my template?
Apologies if something didn't make sense, I'm only quite new to Django.
Upvotes: 1
Views: 64
Reputation: 18727
Yes ,you can use set
for reverse relation (related objects) in the templates too:
{{ for cat_story in category.story_set.all }}
{{cat_story.title }}
{{cat_story.url }}
...
{{ endfor }}
Update: Ah, you used reated_name
, then you should use categories
instead of story_set
. Try category.categories.all
instead of category.story_set.all
.
{{ for cat_story in category.categories.all }}
{{cat_story.title }}
{{cat_story.url }}
...
{{ endfor }}
Update: Yes you can, django database api usage is nearly the same in both views and in the templates. You can check related documentation from here
Above page shows below examples:
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
article1.publications.all()
publication2.article_set.all()
You can use similar syntax in the templates without the parenthesis
{{ for publication in article1.publications.all }}
{{ for article in publication2.article_set.all }}
Upvotes: 3