动态FilePathField问题

时间:2011-09-16 01:44:28

标签: django django-models

我有一个模型,其中我用FilePathField指向的pdf目录的位置基于“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

我试图通过在模型类上使用@property方法动态地将客户端和job_number数据传递到pdf字段,但是我的方法或我的语法都是假的,因为整个pdf字段在管理中消失了。关于我做错了什么的指示?

4 个答案:

答案 0 :(得分:4)

根据您在FileField中的类似功能的后续帖子(请参阅下面的最后一个链接) 而且我无法使上述任何一个工作,我会冒险猜测FilePathField字段类型的尚不可能

我知道传递一个可调用的函数适用于大多数字段的''默认'参数... https://docs.djangoproject.com/en/dev/ref/models/fields/#default ...因为它似乎适用于upload_to ImageField的FieldField (eg https://stackoverflow.com/questions/10643889/dynamic-upload-field-arguments/ ) and参数(例如Django - passing extra arguments into upload_to callable function

是否有兴趣将FilePathField扩展为包含此功能?

答案 1 :(得分:3)

  

是否有兴趣扩展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

希望这有助于那里的人。

答案 2 :(得分:1)

尝试将路径值设置为可调用函数

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)

但我不确定这是否有效,我没有测试过。

答案 3 :(得分:1)

根据Django v1.9 FilePathField 实施添加了此实施:

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)