Haikson

[ Everything is possible. Everything takes time. ]

Собственные FilePathField для Django. Список директорий.

Сегодня встала проблема создания поля со списком директорий. К сожалению стандартные поля не позволяют решать данную задачу, или позволяют, но я этого не нашел. Пришлось писать самому. К счастью изобретение велосипедов не является моим хобби. Поэтому за основу взял код класса FilePathField(models.Field). Задача: передаем классу параметр path при инициализации и на выходе получаем рекурсивный список директорий, находящихся в path. Всё делается предельно просто: создаю пакет cff (custom forms and fields) и заливаем туда два модуля
  1. formfields.py
  2. dbfields.py
Форма, для отображения данных (в нашем случае списка директорий):
# formfields.py
from mysite import settings
import os
from django import forms

class ImagesDirField(forms.ChoiceField):
    def __init__(self, path, match=None, recursive=False, required=True,
                 widget=None, label=None, initial=None, help_text=None,
                 *args, **kwargs):
        self.path, self.match, self.recursive = path, match, recursive
        super(ImagesDirField, self).__init__(choices=(), required=required,
            widget=widget, label=label, initial=initial, help_text=help_text,
            *args, **kwargs)
        self.choices.append(("", ""),)
        for root, dirs, files in os.walk(self.path):
            for f in dirs:
                if self.match is None or self.match_re.search(f):
                    f = os.path.join(root, f)
                    self.choices.append((f, f.replace(path, "", 1).replace("\\", "/"))) # Delete path and replace winbackslashes

        self.widget.choices = self.choices
Поле для модели :-)
# dbfields.py
from django.db import models
from mysite.cff import formfields

class ImagesPathField(models.Field):
    description = "Field Gets Paths List for Images"

    def __init__(self, verbose_name=None, name=None, path="", match=None, recursive=False, **kwargs):
        self.path, self.match, self.recursive = path, match, recursive
        kwargs["max_length"] = kwargs.get("max_length", 100)
        models.Field.__init__(self, verbose_name, name, **kwargs)

    def formfield(self, **kwargs):
        defaults = {
            "path": self.path,
            "match": self.match,
            "recursive": self.recursive,
            "form_class": formfields.ImagesDirField,
        }
        defaults.update(kwargs)
        return super(ImagesPathField, self).formfield(**defaults)

    def get_internal_type(self):
        return "ImagesPathField"
Использование:
from mysite.cff import dbfields
class Directories(models.Model):
    directory = dbfields.ImagesPathField(path = ("%s/img/" % (settings.MEDIA_ROOT)))