Безопасно ли устанавливать __new__ для классов моделей Django? - PullRequest
4 голосов
/ 21 февраля 2012

Этот вопрос отличается от: Использование __new__ в классах, полученных из моделей Джанго, не работает

Этот вопрос спрашивает, как заставить __new__ работать.

Этот вопрос задает : Каковы подводные камни использования __new__ с моделями Django?

В частности, у меня есть следующий код, который существует для установки метода класса в классе, который должен знать, из какого класса он исходит (то есть он должен сказать, вызывается ли он в подклассе или нет). Будет ли это неожиданным образом взорваться?

class Director(models.Model, Specializable, DateFormatter, AdminURL, Supercedable): # my own mixin classes
    # all other properties etc snipped

    @staticmethod # necessary with django models
    def __new__(cls, *args, **kwargs):
        Specializable.create_subclass_translator(cls, install = 'create_from_officer')
        return models.Model.__new__(cls, *args, **kwargs)

Для полноты create_subclass_translator делает что-то вроде этого:

@classmethod
def create_subclass_translator(clazz, Baseclass, install=None):       
    def create_from_other_instance(selfclass, old_instance, properties):
        if selfclass is Baseclass: raise TypeError("This method cannot be used on the base class")
        # snipped for concision
        return selfclass(**properties)

    new_method = classmethod(create_from_other_instance)

    if install and not hasattr(Baseclass, install):
        setattr(Baseclass, install, new_method)

    return new_method

Для тех, кто интересуется, что это делает, метод class create_from_other_instance - это фабрика, которая имитирует изменение экземпляра подкласса модели с одного подкласса на другой, путем копирования свойств базового класса и правильной установки свойства ancestor_link.

1 Ответ

2 голосов
/ 21 февраля 2012

Так как вы правильно называете базовый класс __new__, я не ожидал бы сюрпризов там - он должен просто работать - и, если все сделано неправильно, сразу потерпеть неудачу при создании экземпляра.

У вас не должно быть никаких тонкихошибки там - просто напишите некоторые модульные тесты, которые создают экземпляр этого класса.Если это когда-нибудь станет «неправильным», тесты не пройдут.

...