0

我有一个这样的 Django 模型:

class Competitor(models.Model):
  """
  Competitor model object
  """
  name = models.CharField(max_length=20)
  easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
  hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
  tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
  random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
  min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
  min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
  deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
  replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')

而且我希望能够使用索引访问属性,因此,如果我写competitor[0],它应该返回 的值name

我看过了,根据这个问题,我必须“同时实施__iter__()__getitem__()其他方法”。但我不知道在这个方法中做什么。

任何人都知道如何做到这一点?

4

3 回答 3

0

首先,我要感谢@julianofischer 的回答。它教会了我如何实现我将在这个答案中实现的方法。

首先添加一个字符串列表,其中包含您希望能够访问的字段的名称[]作为类的属性,如下所示:

class Competitor(Model):
  """
  Competitor model object
  """
  name = CharField(max_length=20)
  easy = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
  hard = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
  tematicas = ArrayField(PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
  random_score = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
  min1 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
  min2 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
  deluxe = ArrayField(PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
  replica = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
  _list = [ 'easy', 'hard', 'tematicas', 'random_score', 'min1', 'min2', 'deluxe', 'replica' ]

然后,如果您想同时获取和设置值,则必须实现__getitem__and __setitem__,如下所示:

def __getitem__(self, index: int):
  return self.__dict__[self._list[index]]

def __setitem__(self, index: int, value: list):
  self.__dict__[self._list[index]] = value
  self.save(update_fields=[self._list[index]])

这样,您可以使用__getitem__、 using.__dict__[index]和返回这些字段的值,而使用__setitem__,您可以直接修改这些值。

于 2021-04-03T17:02:17.690 回答
0

如果您只打算获取项目,则必须覆盖__getitem__.

class Competitor(models.Model):
  """
  Competitor model object
  """
  name = models.CharField(max_length=20)
  easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
  hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
  tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
  random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
  min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
  min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
  deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
  replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')

  def __getitem__(self, key):
      if key == 0:
          return self.nome
      elif key == 1:
          return self.easy
      ...
      elif key == 8:
          return self.replica

一种简单的方法是使用列表跟踪属性:

class Competitor(models.Model):
  """
  Competitor model object
  """
  name = models.CharField(max_length=20)
  easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
  hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
  tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
  random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
  min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
  min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
  deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
  replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
  _list = [name, easy, hard, tematicas, random_score, min1, min2, deluxe, replica]

  def __getitem__(self, key):
      return self._list[key]

为了完全实现下标符号 ( []),您还需要实现__setitem__and __delitem__

  def __setitem__(self, index, value):
      self._list[index] = value
于 2021-04-03T01:19:59.093 回答
0

我不知道您是否可以在不映射每个索引的情况下做到这一点。如果您可以确保索引的顺序始终相同,那么这对您有用:

class Competitor:
    def __init__(self):
        self.name = 'Leonardo'

    def __getitem__(self, key):
        if key == 0:
            return self.name

if __name__ == "__main__":
    print(Competitor()[0])  # Leonardo
于 2021-04-03T01:21:05.753 回答