Как обезьяна патч Django?

Я столкнулся с этим сообщением по поводу обезглавливания Django:

from django.contrib.auth.models import User

User.add_to_class('openid', models.CharField(max_length=250,blank=True))

def get_user_name(self):
    if self.first_name or self.last_name:
        return self.first_name + " " + self.last_name
    return self.username

User.add_to_class("get_user_name",get_user_name)

Я понимаю, что это не идеально, и лучше добавить поля и функции к User через отдельную модель Profile.

С учетом сказанного я просто хочу понять, как это будет работать:

  • Где бы я поместил код исправления обезьяны?

  • Когда выполняется запуск кода - только один раз? один раз за запуск интерпретатора Python? один раз за запрос?

  • Предположительно, мне все равно нужно изменить схему БД. Поэтому, если я опустил таблицу User и запустил ./manage.py syncdb, мог бы syncdb "знать", что новое поле было добавлено в User? Если нет, как мне изменить схему?

Ответ 1

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

Код должен выполняться хотя бы один раз для каждого процесса python.

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

Вы, кажется, уже знаете, что это ужасная, ужасная вещь, которую нужно делать и никогда не следует делать для реального кода, поэтому я не буду расстраивать этот момент. Выполнение такого рода вещей - фантастический способ генерировать действительно трудно найти ошибки в вашем коде, в дополнение к коду, который может не работать в будущих версиях Django.

Кроме того, он не будет хорошо работать с Югом, который вы должны использовать.

Ответ 2

поместите файл monkey_patching.py в любой из apps и импортируйте его в файл app __init__.py. то есть:

приложение /monkey _patching.py

#app/monkey_patching.py
from django.contrib.auth.models import User

User.add_to_class('openid', models.CharField(max_length=250,blank=True))

def get_user_name(self):
    if self.first_name or self.last_name:
        return self.first_name + " " + self.last_name
    return self.username

User.add_to_class("get_user_name",get_user_name)

приложение /__ __ INIT. Ру

#app/__init__.py
import monkey_patching