2010-12-02 5 views
2

できるだけ簡潔にします。Djangoのカスタムフィールドに属性を追加します

私は次のカスタムフィールドのようなものを実装することにより、この

{{ video.youtube_url.video_id }} 

を行うことがしたい:

class YouTubeURLField(URLField): 
    description = _("YouTubeURL") 

    def _video_id(self): 
     return re.search('(?<=\?v\=)[\w-]+', self.value) 
    video_id = property(_video_id) 

    def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs): 
     super(YouTubeURLField, self).__init__(**kwargs) 
     kwargs['max_length'] = kwargs.get('max_length', 200) 
     CharField.__init__(self, verbose_name, name, **kwargs) 
     self.validators.append(YouTubeURLValidator(verify_exists=verify_exists)) 

この:

def _video_id(self): 
     return re.search('(?<=\?v\=)[\w-]+', self.value) 
    video_id = property(_video_id) 

がsucessfully「VIDEO_IDを追加しません"私のカスタムYouTubeURLFieldの属性。

他のすべては完璧に動作します。

私はYouTubeのカスタムフィールドの面でデザインの面ではおそらくより良い点があると理解していますが、まずこれがなぜ機能しないのかを理解したいと思います。

答えて

0

私はこのようにしたいと思っていました。なぜなら、デザインの立場からはもっと意味があるように思えるからです。動画IDはYouTube URLの属性であり、モデル自体の属性ではありません。

私はそれを理解しました。 to_python関数をオーバーライドしてYouTubeURLオブジェクトを返します。

class YouTubeURL(object): 
    def __init__(self, value): 
    self.value = value 

    @property 
    def video_id(self): 
    regex = re.compile(r'/v/([A-Za-z0-9\-_]+)', re.IGNORECASE) 

    id = regex.search(self.value) 
    return id.group(1) 

    def __unicode__(self): 
    return "%s" % (self.value,) 

    def __str__(self): 
    return "%s" % (self.value,) 

    def __len__(self): 
    return len(self.value) 

class YouTubeURLField(URLField): 
    description = _("YouTubeURL") 

    __metaclass__ = SubfieldBase 

    def to_python(self, value): 
     return YouTubeURL(value) 

    def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs): 
     super(YouTubeURLField, self).__init__(**kwargs) 
     kwargs['max_length'] = kwargs.get('max_length', 200) 
     CharField.__init__(self, verbose_name, name, **kwargs) 
     self.validators.append(YouTubeURLValidator(verify_exists=verify_exists)) 
2

Djangoフィールドはdescriptorsです。つまり、フィールドにアクセスするとフィールド値が返されるのではなく、フィールド値が返されます。気になる属性を持つオブジェクトを返すには、が必要です。また、定義済みの__unicode__()メソッドが返されます。

0

モデルのプロパティとして使用できない理由はありますか?

{{ sheep.sheep_says }} 
:あなたは、その後にテンプレートにアクセスすることになり

class: Sheep(models.Model): 
    name = models.CharField(max_length=200) 

    @property 
    def sheep_says(self): 
     return "Baa... my name is %s ... baa" % self.name 

:直接フィールド内に含まれていないオブジェクトからデータにアクセスするために、私は頻繁にの線に沿ってパターンを実装するには

関連する問題