【问题标题】:Django Generic DetailView customizationDjango 通用 DetailView 自定义
【发布时间】:2014-01-27 05:51:33
【问题描述】:

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

这是我的详细视图:

    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 中实现它们。

【问题讨论】:

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


    【解决方案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 Inspector 是您处理 CBV 时的朋友。

    更新

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

    导入操作系统 BASE_DIR = os.path.dirname(os.path.dirname(__file__))

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

    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 模式

    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
    

    【讨论】:

    • 您好,感谢您的帖子。睡了8个多小时后,这个想法开始变得清晰。但我想问一下我如何将 DetailView 中使用的根目录传递给我用于遍历目录的函数?我在 [ccbv.co.uk/projects/Django/1.6/django.views.generic.detail/… (CBV Inspector) 中搜索了一些方法,但我找不到任何有用的东西。
    • 所以你要搜索server-side目录?你为什么要那样做?我真的想不出原因,但无论如何我更新了答案。
    • 好的,感谢您的耐心等待。我想我再也不会做咖啡前的帖子了(还在睡觉)。问题是我无法很好地解释这到底是什么意思。在我的 webapp BackupViewer 中,detailView 显示了两件事:1:单击的项目的名称和 2:它所在的根目录。目标是还显示项目中的子文件夹列表及其大小。但问题是我一点也不知道如何遍历DetailView中可视化的项目目录,希望我的英语不会让你太困惑。提前谢谢你。
    • 你问的问题不容易。我将更新我的答案,为您提供一些一般性提示,如果您有任何其他 cmet,请提出不同的问题。
    • 再次感谢您的耐心和帮助。祝你有美好的一天:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    相关资源
    最近更新 更多