Динамический вопрос FilePathField

У меня есть модель, в которой местоположение каталога pdf, на которое я указываю с помощью моего FilePathField, основано на полях "client" и "job_number".

class CCEntry(models.Model):
    client = models.CharField(default="C_Comm", max_length=64)
    job_number = models.CharField(max_length=30, unique=False, blank=False, null=False)
    filename = models.CharField(max_length=64, unique=False, blank=True, null=True)
    pdf = models.FilePathField(path="site_media/jobs/%s %s", match=".*\.pdf$", recursive=True

    @property
    def pdf(self):
            return "site_media/jobs/%s %s" % (self.client, self.job_number)

    def __unicode__ (self):
            return u'%s %s' % (self.client, self.filename)

    class Admin: 
            pass

Я попытался передать данные client и job_number в поле pdf динамически, используя метод @property в классе модели, но мой подход или мой синтаксис неверны, поскольку все поле pdf исчезает в админке. Есть указания на то, что я делаю не так?

4 ответа

Решение

Попробуйте установить значение пути как вызываемую функцию

def get_path(instance, filename):
    return "site_media/jobs/%s_%s/%s" % (instance.client, instance.job_number, filename)


class CCEntry(models.Model):
    ....
    pdf = models.FilePathField(path=get_path, match=".*\.pdf$", recursive=True)

но я не уверен, что это работает, я не проверял это.

Исходя из вашего последующего поста о схожей функциональности в FileField (см. Последнюю ссылку ниже) и моей неспособности заставить что-либо из перечисленного работать, я рискну предположить, что это пока невозможно FilePathField тип поля.

Я знаю, что передача вызываемого объекта работает для большинства параметров по умолчанию для полей... https://docs.djangoproject.com/en/dev/ref/models/fields/... так как это работает для upload_to параметр FieldField (eg https://stackru.com/questions/10643889/dynamic-upload-field-arguments/ ) andImageField` (например, Django - передача дополнительных аргументов в вызываемую функцию upload_to)

Тот, кто заинтересован в расширении FilePathField включить эту функцию?

Кто-нибудь заинтересован в расширении FilePathField для включения этой функции?

Я хотел бы видеть это расширение!

Просто для справки, это решение, которое работало для меня (django 1.3):

    # models.py
    class Analysis(models.Model):
        run = models.ForeignKey(SampleRun)
        # Directory name depends on the foreign key 
        # (directory was created outside Django and gets filled by a script)
        bam_file = models.FilePathField(max_length=500, blank=True, null=True)  

    # admin.py
    class CustomAnalysisModelForm(forms.ModelForm):
        class Meta:
            model = Analysis
        def __init__(self, *args, **kwargs):
            super(CustomAnalysisModelForm, self).__init__(*args, **kwargs)
            # This is an update
            if self.instance.id:
                # set dynamic path
                mypath = settings.DATA_PATH + self.instance.run.sample.name
                self.fields['bam_file'] = forms.FilePathField(path=mypath, match=".*bam$", recursive=True)

    class AnalysisAdmin(admin.ModelAdmin):
        form = CustomAnalysisModelForm

Надеюсь, это поможет кому-то там.

Добавлена ​​реализация этого на основе реализации FilePathField в Django v1.9:

from django.db.models import FilePathField


class DynamicFilePathField(FilePathField):

    def __init__(self, verbose_name=None, name=None, path='', match=None,
                 recursive=False, allow_files=True, allow_folders=False, **kwargs):
        self.path, self.match, self.recursive = path, match, recursive
        if callable(self.path):
            self.pathfunc, self.path = self.path, self.path()
        self.allow_files, self.allow_folders = allow_files, allow_folders
        kwargs['max_length'] = kwargs.get('max_length', 100)
        super(FilePathField, self).__init__(verbose_name, name, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super(FilePathField, self).deconstruct()
        if hasattr(self, "pathfunc"):
            kwargs['path'] = self.pathfunc
        return name, path, args, kwargs

И пример использования:

import os
from django.db import models

def get_data_path():
    return os.path.abspath(os.path.join(os.path.dirname(__file__), 'data'))

class GenomeAssembly(models.Model):
    name = models.CharField(
        unique=True,
        max_length=32)
    chromosome_size_file = DynamicFilePathField(
        unique=True,
        max_length=128,
        path=get_data_path,
        recursive=False)
Другие вопросы по тегам