Добавить атрибут в настраиваемые поля в Django - PullRequest
2 голосов
/ 02 декабря 2010

Я буду максимально кратким.

Я хочу это сделать

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

Не удалось добавить атрибут "video_id" в мой пользовательский YouTubeURLField.

Все остальное работает без нареканий.

Я понимаю, что, возможно, есть лучшие соображения по дизайну с точки зрения настраиваемого поля YouTube, но я бы лучше сначала понял, почему это не работает.

Ответы [ 3 ]

2 голосов
/ 02 декабря 2010

Поля Django являются дескрипторами , что означает, что при доступе к ним возвращается не поле, а значение поля.Вам нужно будет переопределить методы поля Django , чтобы вернуть объект, имеющий атрибуты, которые вам нужны, а также метод __unicode__(), определенный разумно.

0 голосов
/ 04 декабря 2010

Я хотел сделать это таким образом, потому что это кажется более логичным с точки зрения дизайна. Идентификатор видео является атрибутом URL-адреса YouTube, а не самой модели.

Я понял это. Я переопределил функцию 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))
0 голосов
/ 02 декабря 2010

Есть ли причина, по которой вы не можете использовать его как свойство модели?

Чтобы получить доступ к данным из объекта, не содержащегося непосредственно в полях, я часто реализую шаблон в соответствии с:

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

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

К которому вы затем получите доступ в шаблоне:

{{ sheep.sheep_says }}
...