dynamic FilePathField question
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/ ) and
ImageField` (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)
精彩评论