From 224d5ecb8456cd20caa41b43ecdccea9dae37b17 Mon Sep 17 00:00:00 2001 From: Heasummn Date: Thu, 24 Sep 2015 15:04:48 -0500 Subject: [PATCH] Add Tags and navigation through tags Allows user to pick or create Tags in the admin, The user can then apply these Tags to blog posts. Clicking on a Tag will link to a page with allposts of said tag. Closes issue #56. --- contributr/contriblog/admin.py | 3 ++- .../migrations/0002_auto_20150924_1705.py | 26 +++++++++++++++++++ contributr/contriblog/models.py | 7 +++++ .../templates/contriblog/detail.html | 10 ++++++- .../templates/contriblog/index.html | 8 +++++- .../contriblog/templates/contriblog/tag.html | 11 ++++++++ contributr/contriblog/urls.py | 1 + contributr/contriblog/views.py | 6 +++++ 8 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 contributr/contriblog/migrations/0002_auto_20150924_1705.py create mode 100644 contributr/contriblog/templates/contriblog/tag.html diff --git a/contributr/contriblog/admin.py b/contributr/contriblog/admin.py index 00bbacf..f8f0c9f 100644 --- a/contributr/contriblog/admin.py +++ b/contributr/contriblog/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import Post +from .models import * class PostAdmin(admin.ModelAdmin): @@ -9,3 +9,4 @@ class PostAdmin(admin.ModelAdmin): admin.site.register(Post, PostAdmin) +admin.site.register(Tag) diff --git a/contributr/contriblog/migrations/0002_auto_20150924_1705.py b/contributr/contriblog/migrations/0002_auto_20150924_1705.py new file mode 100644 index 0000000..19ae07d --- /dev/null +++ b/contributr/contriblog/migrations/0002_auto_20150924_1705.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('contriblog', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('slug', models.SlugField(unique=True, max_length=200)), + ], + ), + migrations.AddField( + model_name='post', + name='tags', + field=models.ManyToManyField(to='contriblog.Tag'), + ), + ] diff --git a/contributr/contriblog/models.py b/contributr/contriblog/models.py index 70da3bd..f9cdd72 100644 --- a/contributr/contriblog/models.py +++ b/contributr/contriblog/models.py @@ -2,6 +2,12 @@ from django.core.urlresolvers import reverse +# Tag class +class Tag(models.Model): + slug = models.SlugField(max_length=200, unique=True) + + def __str__(self): + return self.slug # Custom queryset manager that only displays posts that have publish set to true. class PostQuerySet(models.QuerySet): @@ -18,6 +24,7 @@ class Post(models.Model): edited_date = models.DateTimeField(auto_now=True) publish = models.BooleanField(default=False) slug = models.SlugField(max_length=200, unique=True) + tags = models.ManyToManyField(Tag) objects = PostQuerySet.as_manager() diff --git a/contributr/contriblog/templates/contriblog/detail.html b/contributr/contriblog/templates/contriblog/detail.html index fab54fc..8bc2c5f 100644 --- a/contributr/contriblog/templates/contriblog/detail.html +++ b/contributr/contriblog/templates/contriblog/detail.html @@ -9,8 +9,16 @@ -

created on {{ object.created_date|date }}, by {{ object.author }}

+ +

+ created on {{ object.created_date|date }}, by {{ object.author }} | Tagged under + {% for tag in object.tags.all %} + {{ tag.slug }}{% if not forloop.last %},{% endif %} + {% endfor %} +

+

{{ object.body|markdown }}

+ {% endblock %} diff --git a/contributr/contriblog/templates/contriblog/index.html b/contributr/contriblog/templates/contriblog/index.html index 1ad1456..fa5206c 100644 --- a/contributr/contriblog/templates/contriblog/index.html +++ b/contributr/contriblog/templates/contriblog/index.html @@ -11,7 +11,13 @@

Contributr blog

{% for object in object_list %}

{{ object.title }}

-

created on {{ object.created_date|date }}, by {{ object.author }}

+ +

+ created on {{ object.created_date|date }}, by {{ object.author }} | Tagged under + {% for tag in object.tags.all %} + {{ tag.slug }}{% if not forloop.last %},{% endif %} + {% endfor %} +

{{ object.body|markdown }}

diff --git a/contributr/contriblog/templates/contriblog/tag.html b/contributr/contriblog/templates/contriblog/tag.html new file mode 100644 index 0000000..4f4e097 --- /dev/null +++ b/contributr/contriblog/templates/contriblog/tag.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} +{% block content %} +
+

Tagged under {{ object.slug }}

+ +
+{% endblock %} diff --git a/contributr/contriblog/urls.py b/contributr/contriblog/urls.py index 36a6303..1d72e9b 100644 --- a/contributr/contriblog/urls.py +++ b/contributr/contriblog/urls.py @@ -5,5 +5,6 @@ urlpatterns = [ url(r'^$', views.BlogIndex.as_view(), name="index"), + url(r'^tags/(?P\S+)$', views.TagDetail.as_view(), name="tag_detail"), url(r'^post/(?P\S+)$', views.BlogDetail.as_view(), name="detail"), ] diff --git a/contributr/contriblog/views.py b/contributr/contriblog/views.py index c185aba..f79b1f9 100644 --- a/contributr/contriblog/views.py +++ b/contributr/contriblog/views.py @@ -13,3 +13,9 @@ class BlogIndex(generic.ListView): class BlogDetail(generic.DetailView): model = models.Post template_name = "contriblog/detail.html" + +# Generic view that lists every post with selected tag. +class TagDetail(generic.DetailView): + model = models.Tag + template_name = "contriblog/tag.html" + slug_url_kwarg = "tag"