Tagging with django-taggit

In this video you will learn an easy way to add tags to your models, and on your site. Tags can be hard if you try to implement them yourself, so don't try and just use this library from the start.

resources

djangostore/settings.py

INSTALLED_APPS = (
    'product',
    'taggit',
)

product/models.py

from datetime import date
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.encoding import python2unicode_compatible

from taggit.managers import TaggableManager

@python_2_unicode_compatible
class Product(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, blank=True)
    sku = models.CharField(max_length=255, blank=True, null=True)
    description = models.TextField()
    price = models.DecimalField(decimal_places=2, max_digits=10)
    active = models.BooleanField(default=True)
    featured = models.BooleanField(default=False)
    weight = models.DecimalField(
        max_digits=8, decimal_places=2, null=True, blank=True)
    height = models.DecimalField(
        max_digits=8, decimal_places=2, null=True, blank=True)
    date_added = models.DateField(null=True, blank=True)

    tags = TaggableManager()

    def __str(self):
        return self.name

    def save(self, kwargs):
        if not self.pk:
            self.date_added = date.today()

        if self.name and not self.slug:
            self.slug = slugify(self.name)

        if not self.sku:
            self.sku = self.slug
        super(Product, self).save(kwargs)

product/views.py

from django.views.generic import DetailView, ListView

from taggit.models import Tag

from .models import Product


class TagMixin(object):
    def get_context_data(self, kwargs):
        context = super(TagMixin, self).get_context_data(kwargs)
        context['tags'] = Tag.objects.all()
        return context

class ProductDetail(DetailView):
    template_name = 'product/detail.html'
    context_object_name = 'product'
    model = Product


class ProductIndex(TagMixin, ListView):
    template_name = 'product/index.html'
    model = Product
    paginate_by = '10'
    queryset = Product.objects.all()
    context_object_name = 'products'

class TagIndexView(TagMixin, ListView):
    template_name = 'product/index.html'
    model = Product
    paginate_by = '10'
    context_object_name = 'products'

    def get_queryset(self):
        return Product.objects.filter(tags__slug=self.kwargs.get('slug'))

product/urls.py

from django.conf.urls import *

from .views import ProductDetail, ProductIndex, TagIndexView

urlpatterns = patterns(
    '',
    url(r'^$', ProductIndex.as_view(), name='products'),
    url(r'^tag/(?P<slug>[-\w]+)/$', TagIndexView.as_view(), name='tagged'),
    url(
        r'^(?P<pk>\d+)-(?P<slug>[-\w]+)/$', ProductDetail.as_view(),
        name='product'),
)

product/templates/products/index.html

{% extends 'base.html' %}

{% block content %}
<div class="row">
  <div class="col-sm-2">
     <div class="panel panel-default">
      <div class="panel-heading">
        Categories
      </div>
      <div class="panel-body">
        <ul>
          {% for tag in tags %}
            <li><a href="{% url 'tagged' tag.slug %}">{{ tag.name }}</a></li>
          {% empty %}
            <li>No Tags</li>
          {% endfor %}
        </ul>
      </div>
    </div>
  </div>
  <div class="col-sm-10">
    {% for product in products %}
      <div class="panel panel-default">
        <div class="panel-heading">
          {{ product.name }}
        </div>
        <div class="panel-body">
          {{ product.description }}
          <br />
          <div class="row">
            <div class="col-sm-2">
              ${{ product.price }}
            </div>
            <div class="col-sm-2">
              <button class="btn btn-default btn-sm">Add to Cart</button>
            </div>
          </div>
        </div>
      </div>
    {% empty %}
      There are no products, sorry.
    {% endfor %}
  </div>
</div>
{% endblock %}
comments powered by Disqus