2016-08-31 4 views
1

Я хочу, чтобы все мои модели, чтобы переопределить __str__ метод аналогичным образом:Как написать общую реализацию метода __str__ для всех моих моделей в Django?

class MyModel1(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self,self.to_show): 
      return str(getattr(self, self.to_show)) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

class MyModel2AndSoOn(models.Model): 
    another_param = models.CharField(max_length=255) 
    # same implementation of `__str__` but with another_param 

Я не хочу повторять один и тот же код для всех моих моделей, поэтому я попытался удел:

class ShowModel(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self,self.to_show): 
      return str(getattr(self, self.to_show)) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

class MyModel1(ShowModel): 
    another_param = models.CharField(max_length=255) 

class MyModel2(ShowModel): 
    another_param = models.CharField(max_length=255) 

но это портит с id от MyModel1 и MyModel2 путем замены id на указатель на ShowModel. Как написать общую реализацию метода __str__ для моих моделей без наследования или как предотвратить обработку класса ShowModel как модели Django?

Upd: Я использовал abstract модель как alecxe предложил, но она закончилась с сообщением об ошибке:

in _show 
    return str(getattr(self, self.to_show)) 
File "/path/to/my/project/env3/lib/python3.5/site-packages/django/db/models/fields/__init__.py", line 188, in __str__ 
model = self.model 
AttributeError: 'CharField' object has no attribute 'model' 

Upd Все работает отлично, если я задаю значение для name области моей модели объекта. Всего решение:

class ShowModel(object): 
    to_show = 'name' 

    def _show(self): 
      if hasattr(self,self.to_show): 
       return str(getattr(self, self.to_show)) 
      elif hasattr(self,'id'): 
       return str(getattr(self, 'id')) 
      else: 
       return str(self) 

    def __str__(self): 
     return self._show() 

    class Meta: 
     abstract = True 

class MyModel1(ShowModel): 
    name = models.CharField(max_length=255) 
    to_show = 'name' 

class MyModel2(ShowModel): 
    another_param = models.CharField(max_length=255) 
    to_show = 'another_param' 

в тесте:

ua = MyModel1() 
ua.name = 'hi' 
print(ua) 
#prints hi 

ub = MyModel2() 
ub.another_param = 'hi again' 
print(ub) 
#prints hi again 

ответ

1

Вам нужно создать abstract model:

class ShowModel(models.Model): 
    name = models.CharField(max_length=255) 

    def __init__(self): 
     self.to_show = 'name' 

    def _show(self): 
     if hasattr(self, "to_show"): 
      return str(getattr(self, "to_show")) 
     else: 
      return str(getattr(self, 'id')) 

    def __str__(self): 
     return self._show() 

    class Meta: 
     abstract = True 

И, как для последующих вопросов и благодаря @itzmeontv, вы должны заменить self.to_show на «to_show» при вызове hasattr() и getattr().

+0

Это был неожиданно простой ответ! Но это дало следующую ошибку: вопрос обновления. –

+0

Ни один из моих классов не имеет атрибута 'show'. Если вы укажете 'to_show', то' hasattr (self, 'to_show') 'проверяет, имеет ли' MyModel1' или 'ShowModel' атрибут' to_show', но то, что я хочу проверить, является ли 'MyModel' или' ShowModel' значением ' to_show', то есть атрибут 'name' –

+0

Но спасибо за решение в любом случае! –

 Смежные вопросы

  • Нет связанных вопросов^_^