【问题标题】:Django, how to do CRUD with django-mptt?Django,如何用 django-mptt 做 CRUD?
【发布时间】:2012-07-15 12:34:17
【问题描述】:

我们如何使用 通用视图django-mptt 实现 CRUD 功能?我搜索了很多,找不到一个教程/示例代码。

假设我们有一个课程层次结构或类别层次结构,或类似的东西......我们如何添加/删除/更新/读取它们??

例如我有这个模型:

from django.db import models
from mptt.models import MPTTModel , TreeForeignKey


class Genre(MPTTModel):
    name            = models.CharField(max_length = 50 , unique = True)
    parent          = TreeForeignKey('self' , null = True , blank = True , related_name = 'children')

    class MPTTMeta:
        order_insertion_by = ['name']

这个views.py:

from django.views.generic.list_detail import object_list
from mp.models import Genre

def genres_list(request):
    ''' Shows all of the genres '''
    return object_list(request,
            queryset = Genre.tree.all() ,
            template_name = 'genres.html' ,
            # template_object_name = 'nodes' ## Adding "nodes" variable didn't solve the problem
    )

好吧...我收到此错误(错误在行号“5”中:{% recursettree nodes %}):

Caught VariableDoesNotExist while rendering: Failed lookup for key [nodes] in u"[{'paginator': None, 'is_paginated': False, 'page_obj': None, 'nodes_list': [<Genre: Genre object>, <Genre: Genre object>, <Genre: Genre object>, <Genre: Genre object>]}, {'csrf_token': <django.utils.functional.__proxy__ object at 0x7f5bb810f090>}, {'perms': <django.utils.functional.__proxy__ object at 0x7f5bb810ff10>, 'messages': <django.contrib.messages.storage.user_messages.LegacyFallbackStorage object at 0x324af50>, 'user': ....................................

    <html>
2   
3       {% load mptt_tags %}
4       <ul>
5           {% recursetree nodes %}
6           <li>
7               {{node.name}}

【问题讨论】:

    标签: django django-models crud django-mptt


    【解决方案1】:

    具有 MPTT 模型和基于类的通用视图的简单 CRUD 应用程序 (Django 1.4 The function-based implementation has been deprecated)。

    开始吧

    urls.py

    from django.conf.urls.defaults import patterns, include, url
    from django.views.generic import DetailView, ListView, CreateView, UpdateView
    from genre.models import Genre
    
    urlpatterns = patterns('',
        url(r'detail/(?P<pk>\d+)', DetailView.as_view(model=Genre), name="genre_detail",),
        url(r'update/(?P<pk>\d+)', UpdateView.as_view(model=Genre), name="genre_update",),
        url(r'create', CreateView.as_view(model=Genre), name="genre_create",),
        url(r'list', ListView.as_view(model=Genre), name="genre_list",),
    )
    

    models.py

    from django.core.urlresolvers import reverse
    from django.db import models
    from mptt.models import MPTTModel
    
    
    class Genre(MPTTModel):
        name = models.CharField(max_length=50 , unique=True)
        parent = models.ForeignKey('self' , null=True , blank=True , related_name='children')
    
        def get_absolute_url(self):
            return reverse('genre_detail', kwargs={'pk': self.pk, })
    
        class MPTTMeta:
            order_insertion_by = ['name']
    

    templates/genre_detail.html

    <html>
    <body>
    
    <div>Object: {{ object }}</div>
    <div>Object's name: {{ object.name }}</div>
    <div>Object's parent: {{ object.parent }}</div>
    
    </body>
    </html>
    

    templates/genre_form.html

    <html>
    <body>
    
    <form action="" method="post">
    {% csrf_token %}
    {{ form.as_ul }}
    
    <button>save</button>
    </form>
    </body>
    </html>
    

    templates/genre_list.html

    {% load mptt_tags %}
    <html>
    <body>
    <ul class="root">
        {% recursetree object_list %}
            <li>
                {{ node.name }}
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>
    </body>
    </html>
    

    就是这样。

    今天有空,在github上分享了这个项目https://github.com/kaygorodov/simple-crud-mptt

    如何定义自己的基于类的视图?

    genre/views.py

    from django.view.generic import UpdateView
    class MyCustomUpdateView(UpdateView):
        model = Genre
    
        def get_form_kwargs(self):
            """
            Returns the keyword arguments for instanciating the form.
            """
            kwargs = super(MyCustomUpdateView, self).get_form_kwargs()
            kwargs.update({'my_first_param_to_init_form': 1,
                          'my_second_param_to_init_form': 2,
            })
            return kwargs
    

    流派/urls.py

    url(r'update/(?P<pk>\d+)', MyCustomUpdateView.as_view(), name="genre_update",),
    

    【讨论】:

    • 这太棒了!!!谢谢伙计..我很感激:)不过,我想我必须围绕通用视图编写一些包装器以进行更多自定义...大赞:)
    • 不客气。如果您需要自定义,您可以指定自己的基于类的视图,我已经编辑了我的答案以展示如何做到这一点。
    • 在我的上一个项目中,我只使用了基于类的视图。它简单、快速,您可以获得更好的设计。
    • 您可以删除它,所有子节点也将被删除。当 Django 删除一个对象时,默认情况下它会模拟 SQL 约束 ON DELETE CASCADE 的行为——换句话说,任何具有指向要删除的对象的外键的对象都将与它一起被删除。 todoc
    • 我已将“删除操作”添加到project
    猜你喜欢
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2010-10-11
    • 2012-09-27
    • 1970-01-01
    相关资源
    最近更新 更多