2016-05-10 11 views
3

Я хотел бы настроить форму регистрации пользователя в Django/Мезонин разрешить только определенные адреса электронной почты, поэтому я попытался обезьяньего пластыря следующим образом:Добавление проверки в Django формы User

# Monkey-patch Mezzanine's user email address check to allow only 
# email addresses at @example.com. 
from django.forms import ValidationError 
from django.utils.translation import ugettext 
from mezzanine.accounts.forms import ProfileForm 
from copy import deepcopy 
original_clean_email = deepcopy(ProfileForm.clean_email) 
def clean_email(self): 
    email = self.cleaned_data.get("email") 
    if not email.endswith('@example.com'): 
     raise ValidationError(
      ugettext("Please enter a valid example.com email address")) 
    return original_clean_email(self) 
ProfileForm.clean_email = clean_email 

Этот код добавляется вверху одного из моих models.py.

Однако, когда я runserver я получаю страшный

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 

Если добавить

import django 
django.setup() 

тогда python manage.py runserver просто зависает, пока я ^C.

Что я должен делать, чтобы добавить эту функцию?

+0

Из интереса, почему вы считаете, что добавление 'django.setup()' было возможным исправлением? Это означает, что когда вы используете Django в автономных сценариях, вы никогда не должны использовать его в своем 'models.py'. – Alasdair

+1

Я знаю это сейчас! Я использовал его в автономных скриптах, чтобы настроить нужные мне модели и не понимал, что он не будет работать в рамках реального проекта Django. – xnx

ответ

2

Создайте файл myapp/apps.py для одного из приложений (я имею использование myapp здесь), и определить класс конфигурации приложения, который делает monkeypatching в методе ready().

from django.apps import AppConfig 

class MyAppConfig(AppConfig): 
    name = 'myapp' 

    def ready(self): 
     # do the imports and define clean_email here 
     ProfileForm.clean_email = clean_email 

Затем используйте 'myapp.apps.MyAppConfig' вместо 'myapp' в настройках INSTALLED_APPS.

INSTALLED_APPS = [ 
    ... 
    'myapp.apps.MyAppConfig', 
    ... 
] 

Возможно, вам понадобится поставить Mezzanine над конфигурацией приложения, чтобы он работал.

+0

Спасибо, Alasdair. Я обнаружил, что мне нужно добавить 'name = 'myapp'' в определение класса MyAppConfig. Можете ли вы предоставить ссылку на соответствующую документацию или учебник Django в своем ответе? Найти это нелегко. – xnx

+0

Я не уверен в лучшем месте для ссылки. Вы можете найти документы для [django apps] (https://docs.djangoproject.com/en/1.9/ref/applications/#configuring-applications). В частности, метод ['ready'] (https://docs.djangoproject.com/en/1.9/ref/applications/#django.apps.AppConfig.ready) является подходящим местом для регистрации сигналов, а в вашем случае , сделайте требуемую передачу monkeypatching. – Alasdair

+0

Я не понимал, что требуется «имя», я обновил ответ. – Alasdair