Задать вопрос
Ответы пользователя по тегу Python
  • Как перегрузить __getattribute__ класса через декоратор в Python?

    @shdprogrammer Автор вопроса
    Да, извиняюсь, надо было наверное привести полную задачу, а не ее часть. Есть сайт на django. Нужно перевести на несколько языков его базу. Решил попробовать сделать это через декоратор модели. Декоратор добавляет поля с префиксом языка, это сделано. Теперь требуется в зависимости от установленного языка обращаться к стандартному полю, или к полю с префиксом. Для этого хотел перегрузить __getattribute__ модели. Хотел сделать это в том же декораторе. Плюс кастомный менеджер что бы перехватывать обращения и направлять их к нужным полям.

    Декоратор:
    class AAA(object):
    
        def __init__(self, *fields):
    
            self.fields = fields
    
        def __call__(self, cls):
            meta = cls._meta
    
            for field_name in self.fields:
    
                try:
                    field = meta.get_field_by_name(field_name)[0]
                except IndexError:
                    raise Exception('Field not found in %s?' % cls)
    
                # костыль
                params = {'verbose_name': getattr(field, 'verbose_name', None),
                          'blank': getattr(field, 'blank', None),
                          'null': getattr(field, 'null', None),
                          'choices': getattr(field, 'choices', None),
                          'default': getattr(field, 'default', None),
                          'max_length': getattr(field, 'max_length', None),
                          'help_text': getattr(field, 'help_text', None)}
                params = {k: v for k, v in params.iteritems() if v}
    
                for l in dict(settings.LANGUAGES).iterkeys():
    
                    if l == settings.DEFAULT_LANGUAGE:
                        continue
    
                    fname = '%s_%s' % (l, field_name)
                    ftype = field.__class__.__name__
                    cls.add_to_class(fname, getattr(models, ftype)(**params))
    
            cls.add_to_class('objects', InternationalizedManager())
    
            return cls


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