Настройка Django Generic DetailView

Как именно я могу настроить общий DetailView в Django. Например, в моем веб-приложении, которое показывает все резервные копии в заданном корневом каталоге вместе с их размером, я в основном использую общие представления для отображения содержимого, но я не имею ни малейшего представления, как справиться с настройкой. Это учебник по Django - страница DetailView.

Это мой DetailView:

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

Это мой URL:

    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.


person Angel Elenkov    schedule 08.01.2014    source источник


Ответы (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 добавляет это по умолчанию):

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. Что бы я сделал, так это создать простое представление (не DetailView) с именем traverse и добавить следующие шаблоны URL-адресов в свой 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
person Serafeim    schedule 08.01.2014
comment
Привет, спасибо за ваш пост. После более чем 8 часов сна идея начинает проясняться. Но я хотел бы спросить, как именно я могу передать корневой каталог, который используется в DetailView, функции, которую я использую для просмотра каталогов? Я ищу какой-нибудь метод в [ccbv.co .uk / projects / Django / 1.6 / django.views.generic.detail / (CBV Inspector), но я не нашел ничего полезного. - person Angel Elenkov; 09.01.2014
comment
Итак, вы хотите выполнить поиск в каталоге на стороне сервера? Почему ты хочешь это сделать? Я действительно не могу придумать причину, но в любом случае я обновил ответ. - person Serafeim; 09.01.2014
comment
Хорошо, спасибо за терпение. Думаю, я больше никогда не буду делать посты перед кофе (все еще сплю). Дело в том, что я не мог хорошо объяснить, в чем именно смысл. В моем веб-приложении BackupViewer detailView показывает две вещи: 1: имя проекта, по которому выполняется щелчок, и 2: корневой каталог, в котором он находится. Цель состоит в том, чтобы показать также список вложенных папок в проекте и их размер. Но проблема в том, что я не имею ни малейшего представления о том, как перемещаться по каталогу проекта, который визуализируется в DetailView, надеюсь, мой английский вас не слишком смущает. Заранее спасибо. - person Angel Elenkov; 09.01.2014
comment
То, о чем вы спрашиваете, непросто. Я обновлю свой ответ, чтобы дать вам несколько общих советов по этому поводу, и если у вас есть другие комментарии, задайте другой вопрос. - person Serafeim; 09.01.2014
comment
Еще раз спасибо за терпение и помощь. Хорошего дня :) - person Angel Elenkov; 09.01.2014