我如何在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中实现它们。
答案 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