开发者

dynamic FilePathField question

开发者 https://www.devze.com 2023-04-05 18:57 出处:网络
I have a model where the location of pdf directory I\'m pointing to with my FilePathField is based on the \"client\" and \"job_number\" fields.

I have a model where the location of pdf directory I'm pointing to with my FilePathField is based on the "client" and "job_number" fields.

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

I've tried to pass the client and job_number data to the pdf field dynamically by using a @property method on the model class, but either my approach or my syntax is fualty because the entire pdf field disappears in the admin. Any po开发者_开发问答inters on what I'm doing wrong?


Based on your subsequent post on similar functionality in the FileField (see last link below) And my inability to get any of the above to work, I'm gonna hazard a guess that it's not yet possible for the FilePathField field type.

I know that passing a callable works for most fields' 'default' parameters... https://docs.djangoproject.com/en/dev/ref/models/fields/#default ... as it appears to work for the upload_to param of FieldField (eg https://stackoverflow.com/questions/10643889/dynamic-upload-field-arguments/ ) andImageField` (eg Django - passing extra arguments into upload_to callable function )

Anyone interested in extending FilePathField to include this feature?


Anyone interested in extending FilePathField to include this feature?

I'd love to see this extension!

Just for the record, this is the solution that worked for me (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

Hope this helps somebody out there.


try to set the path value as callable function

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)

but I'm not sure if this works, I didn't test it.


Added an implementation of this based on Django v1.9 FilePathField implementation:

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

And example use:

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消