Django Generic DetailView自定义

时间:2014-01-08 21:52:20

标签: django python-2.7 django-generic-views

我如何在Django中自定义一般的DetailView。例如,在我的webapp中显示给定根目录中的所有备份及其大小,我主要使用通用视图来显示内容,但我对如何处理自定义没有任何想法。这是Django tutorial - DetailView page

这是我的DetailView:

    class ProjectDetailView(LoginRequiredMixin, DetailView):
        model = Project
        template_name = "projects_portal/details.html"

这是我的网址:

    url(r'^projects_portal/(?P<pk>\d+)/view/$', ProjectDetailView.as_view(), name="projects_details"),

这是模型:

    class Project(models.Model):
        root_dir = models.CharField(blank=False, null=False, max_length=2000, verbose_name=_(u"project root directory"))
        project_name = models.CharField(blank=False, null=False, max_length=200, verbose_name=_(u"project name"))
        total_backups_size = models.IntegerField(blank=True, null=True, verbose_name=_(u"total backups size"))
        earliest_backup = models.DateTimeField(blank=True, null=True, verbose_name=_(u"earliest backup"))
        latest_backup = models.DateTimeField(blank=True, null=True, verbose_name=_(u"latest backup"))

这是我的.html:

{% extends "projects_portal/base.html" %}

{% block title %}Details{% endblock %}

{% block extracss %}
<style>
    div{font-size:24px;}
    .col-md-2{width:400px}
</style>
{% endblock extracss %}

{% block content %}
        <table class="table table table-hover">
            <tr>
             <div class="row top-buffer">
                 <td><div class="col-md-1"><strong>Root directory:</strong></div></td>
                 <td><div class="col-md-2">{{project.root_dir}}</div></td>
            </div>
            </tr>
            <tr>
                <div class="row top-buffer">
                    <td><div class="col-md-1"><strong>Project name:</strong></div></td>
                    <td><div class="col-md-2">{{project.project_name}}</div></td>
                </div>
            </tr>
            <tr><td></td><td></td></tr>
        </table>
            <div class="row">
                <div class="col-md-2 col-md-offset-5 text-center">
                    <td>
                        <div class="col-md-1 col-md-offset-1 text-center"><a href="{% url 'projects_portal' %}"><button class="btn btn-success btn-lg">OK</button></a></div>
                    </td>
                    <td></td>
                </div>
            </div>

{% endblock %}

问题是我想在通用detailView中添加一些内容,以便它必须可视化给定项目中所有子文件夹的列表并显示它们的大小。我准备了两个函数来处理这个问题:

    def traverse_dir(path):
            path_len = len(path)
            dir_dict = {}
            for dirName, subdirList, fileList in os.walk(path):
                dir_size = get_size(dirName)               
                dir_dict[dirName[path_len:]] = dir_size
            return dir_dict    

    def get_size(start_path = '.'):
        total_size = 0
        for dirpath, dirnames, filenames in os.walk(start_path):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                total_size += os.path.getsize(fp)
        return total_size

第一个遍历根目录并使用第二个目录获取每个目录的大小。功能经过测试,没问题。问题是如何在通用DetailView中实现它们。

1 个答案:

答案 0 :(得分:1)

要向DetailView添加内容,请覆盖get_context_data方法。例如,如果您将以下方法添加到ProjectDetailView类:

def get_context_data(self, **kwargs):
    context = super(ProjectDetailView, self).get_context_data(**kwargs)
    context['hello'] = "Hello, world"
    return context

您的模板中会有一个名为hello的额外上下文变量,因此您可以使用{{ hello }}输出它。

提示:当你处理CBV时,CBV Inspector是你的朋友。

<强>更新

OP希望将django正在运行的目录传递给他的traverse_dir函数。为此,您可以将以下内容添加到settings.py(django 1.6默认添加):

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

现在,您可以像这样更改get_context_path ProjectDetailView方法:

from django.conf import settings

def get_context_data(self, **kwargs):
    context = super(ProjectDetailView, self).get_context_data(**kwargs)
    context['dirs'] = traverse_dir(settings.BASE_PATH)
    return context

现在,您的上下文中将有一个dirs变量,可以使用(例如){% for %}循环输出。

注意:我没有检查traverse_dir是否按预期工作。

更新2

事实证明,OP有一个不同的问题:如何使用django显示文件夹层次结构。我要做的是创建名为traverse的简单视图(而非DetailView)并在我的urls.py

中添加以下网址模式
url(r'^traverse/(.+)*', 'views.test.traverse', name='traverse' ),

现在,traverse视图可以像这样实现:

def traverse(request, segments=""):
    segments = segments.split(r'/')
    # segments is an array of the url paths
    # construct the path of the folder you want to view here
    # by concatenate settings.BASE_PATH with the url components

    # finally output the contents of the folder by creating links
    # which concatenate the segments with the contents of the folder