Wiki

Clone wiki

django-mptt-demo / Home

Welcome to Django Mptt Demo

Welcome to django mptt demo module this demo provides how to create tree level category and demonstration of mtpp library

Django Mtpp demo features

  • Create Tree level category
  • Display tree level category list in admin panel
  • Display category as tree in another db relation like forenkeyTree (example used in product model)

This demo demonstrate use of django-mptt model.

Go ahead and try:

$ git clone https://cyberkishor@bitbucket.org/cyberkishor/django-mptt-demo.git

Requirements

  • django-mptt

Here's an example of some Python code:

#!python
#models.py
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey

from decimal import Decimal
from django.utils.translation import ugettext_lazy as _

# Create your models here.
class Category(MPTTModel):
    name = models.CharField(max_length=100, blank=False, unique=True)
    description = models.TextField(blank=True, null=True)

    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)

    class MPTTMeta:
        order_insertion_by = ['name']

    class Meta:
        verbose_name_plural = u"Categories"

    def __str__(self):              # __unicode__ on Python 2
        return self.name


class Product(models.Model):
    code = models.CharField(max_length=50, primary_key=True)
    name = models.CharField(max_length=100, blank=True)
    category = TreeForeignKey('Category', null=True, blank=True, db_index=True)
    image = models.ImageField(upload_to='foto', height_field=None, width_field=None, max_length=100, blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    stocks = models.IntegerField(default=0, blank=True)

    #PRICES
    priceAustria = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal('0.00'), verbose_name="Recomended Price", blank=True, null=True)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

    def image_img(self):
        if self.image:
            return u'<img src="%s" width="75" height="75" />' % (self.image.url)
        else:
            return '(No image)'
    image_img.short_description = 'Image'
    image_img.allow_tags = True

Now Copy and Peste inside admin.py

#!python
#admin.py

from django.contrib import admin

from mptt.admin import MPTTModelAdmin

from .models import Category, Product

# Register your models here.
class CategoryAdmin(MPTTModelAdmin):
    fields = ['name', 'description', 'parent']
    list_display = ('name', )

    mptt_level_indent = 15

admin.site.register(Category, CategoryAdmin)


class ProductAdmin(admin.ModelAdmin):
    ordering = ('code',)
    fieldsets = [
        (None, {'fields': ['code', 'stocks', 'image', 'category']}),
        (None, {'fields': ['name', 'description',]}),
        ('Prices', {'fields': ['priceAustria'], 'classes': ['grp-collapse  grp-closed']}),
    ]
    # change_list_template = 'admin/product_change_list.html'
    list_display = ('code', 'name', 'category')
    search_fields = ['code']

    list_filter = ('name',)


admin.site.register(Product, ProductAdmin)

Now inside view.py

#!python

#views.py
from django.shortcuts import render
from django.views.generic.list import ListView
import datetime
from .models import Category, Product
from .forms import CategoryForm

class CategoryListView(ListView):
    template_name = 'category_list.html'
    model = Category

    def get_context_data(self, **kwargs):
        context = super(CategoryListView, self).get_context_data(**kwargs)
        context['now'] = datetime.datetime.now()
        context['category_form'] = CategoryForm()
        context['products'] = Product.objects.all()
        return context

and need to setup template for display hierarchy inside the template:

#!html

#category_list.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django Mtpp Demo | Category List</title>
</head>
<body>
    <h1>Category Tree</h1>
    {% load mptt_tags %}


    <ul>
        {% recursetree category_list %}
            <li>
                {{ node.name }}
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>


    <h2>Category Tree Select </h2>

    <div class="category">
        <form action="." method="get"></form>
        {{ category_form.as_p }}

        <input type="submit" value="Go" />
    </div>

    <h2>Multiple Select</h2>

    <select name="classifiers" multiple="multiple" size="10">
        {% for node,structure in category_list|tree_info:"ancestors" %}
            {% if node.is_child_node %}
                <option value="{{ node.pk }}">
                    {{ structure.ancestors|tree_path }} :: {{ node }}
                </option>
            {% endif %}
        {% endfor %}
    </select>


</body>
</html>

For more detail : http://django-mptt.github.io/django-mptt/

Have fun!

Updated