2011-09-16 72 views
0

我有一個模型,其中我指向我的FilePathField的pdf目錄的位置基於「客戶端」和「作業編號」字段。動態FilePathField問題

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領域,但無論是我的方法還是我的語法是fualty因爲整個PDF場在消失管理員。任何指針我做錯了什麼?

+0

儘量只返回路徑,而不是使用屬性裝飾,同時還改變了名稱函數,只是爲了清晰起見,像get_pdf_path。 – Brandon

+0

好吧,但如果我消除裝飾器並更改函數名稱,如何捕獲FilePathFields「路徑」參數中返回的值? – kjarsenal

+0

您將參數設置爲函數的結果: FilePathField(path = get_pdf_path(),match = ...)。此外,您需要在定義字段之前在類中定義函數。 – Brandon

回答

0

嘗試設置路徑值作爲可調用的函數

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) 

,但我不知道,如果這個工程,我沒有測試它。

+0

拋出一個類型錯誤「強制爲Unicode:需要字符串或緩衝區,找到的函數」我將繼續使用它。 – kjarsenal

+0

我想你需要將__unicode__方法更改爲返回unicode值。像: def __unicode__(self):return unicode(u'%s%s'%(self.client,self.filename)) – jargalan

+0

pdf = models.FilePathField(path = get_path(),...) – Brandon

4

基於你對類似的功能,隨後的後中的FileField(見下面的最後一個環節) 而我無法得到任何上述的工作,我會大膽地猜測,它的沒有可能FilePathField字段類型。

我知道,通過對大多數字段的‘默認’參數的可調用的作品...... https://docs.djangoproject.com/en/dev/ref/models/fields/#default ...因爲它似乎爲upload_to PARAM FieldField (eg https://stackoverflow.com/questions/10643889/dynamic-upload-field-arguments/) and ImageField`(如Django - passing extra arguments into upload_to callable function

任何人的工作有興趣擴展FilePathField以包含此功能?

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 

希望這有助於有人在那裏。

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)