django forms.ModelForm проблема проверки - PullRequest
1 голос
/ 11 апреля 2011

У меня есть модель с некоторыми полями.

У меня есть форма модели, которая представляет часть вышеупомянутой модели.Я должен сделать несколько пользовательских проверок.Некоторые поля зависят от других.Например, поля ввода пароля и подтверждения пароля должны быть одинаковыми.Он привязан к серверной системе.

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

Затем я должен проверить пароль в соответствии с ограничениями, установленными в серверной части.Мне нужно использовать API для этого.Я должен передать имя пользователя с паролем, чтобы использовать эту команду (это глупо, но я не могу ее изменить.)

Если имя пользователя вызвало ошибку проверки в его методе, тогда метид проверки пароля не может использовать sel.cleaned_data ['login']

вот код.

class PEMUserDetails(models.Model):
    #Keys and IDs
    domain = models.OneToOneField('GIBOSite', primary_key=True)
    domain_name = models.CharField(unique=True, max_length=100)
    # Details
    PEM_login_id = models.CharField(max_length=32, unique=True)
    PEM_password = models.CharField(max_length=32)
    PEM_password_confirm = models.CharField(max_length=32)
    FTP_login = models.CharField(max_length=32, blank=True, null=True)
    FTP_password = models.CharField(max_length=32, blank=True, null=True)
    FTP_host_name = models.CharField(max_length=256, blank=True, null=True)
    def __unicode__(self):
        return self.domain_name
    def link_to(self, gibo_site):
        self.domain = gibo_site
        self.domain_name = gibo_site.domain

class PEMUserDetailsForm(forms.ModelForm):
    PEM_password = forms.CharField(widget=forms.PasswordInput)
    PEM_password_confirm = forms.CharField(widget=forms.PasswordInput)
    class Meta:
        model = PEMUserDetails
        exclude = ('domain', 'domain_name', 'FTP_login', 'FTP_password', 'FTP_host_name')


    def clean_PEM_login_id(self):
        login = self.cleaned_data['PEM_login_id']
        try:
            g = PEMUserDetails.objects.get(PEM_login_id=login)
            raise forms.ValidationError("This Login ID is already taken, please choose another.")
        except PEMUserDetails.DoesNotExist:
                p = PBA()
                pem_account = p.BM.UserValidate_API(login)
                if pem_account['AccountID'] == 0:
                    pass
                else:
                    raise forms.ValidationError("This Login ID is already taken, please choose another.")
                validation = p.BM.GetLoginSettings_API()
                m = re.match(validation['ManualLoginMask'], login)
                if m == None:
                    raise forms.ValidationError(validation['LoginAlert'])
                valid_login = (login == m.group(0))
                if len(login) > validation['LoginMinLength'] and len(login) < validation['LoginMaxLength'] and valid_login:
                    pass
                else:
                    raise forms.ValidationError(validation['LoginAlert'])
        return login

    def clean_PEM_password(self):
        p = PBA()
        login = self.cleaned_data['PEM_login_id']
        password = self.cleaned_data['PEM_password']
        validation = p.BM.GetLoginSettings_API()
        if len(password) > validation['PwdMinLength']:
            pass
        else:
            raise forms.ValidationError("Password must be more than %s characters long" % validation['PwdMinLength'])
        passwd_status = p.BM.UserForVendorValidate_API(login, password)
        if passwd_status['passwordStrength'] == '':
            pass
        else:
            raise forms.ValidationError(passwd_status['passwordStrength']) 
        return password

    def clean_PEM_password_confirm(self):
        p = self.cleaned_data['PEM_password']
        c = self.cleaned_data['PEM_password_confirm']
        if c == p:
            pass
        else:
            raise forms.ValidationError("The passwords you submitted do not match")
        return c

Я справился с этим с помощью обычной формы и сопоставил ее с классом модели.Это своего рода бегство от проблемы.Является ли это ограничением модели в django 1.1

оболочка Python показывает это

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from gibo.deployment.models import PEMUserDetailsForm
>>> from django.http import QueryDict
>>> post = QueryDict("PEM_login_id=beefsupreme&PEM_password=beef1234&PEM_password_confirm=beef123")
>>> f = PEMUserDetailsForm(post)
>>> f.is_valid()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 120, in is_valid
    return self.is_bound and not bool(self.errors)
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 111, in _get_errors
    self.full_clean()
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 243, in full_clean
    value = getattr(self, 'clean_%s' % name)()
  File "/home/niall/public_html/projects/GIBO/dev/projects/signup/gibo/../gibo/deployment/models.py", line 776, in clean_PEM_password
    login = self.cleaned_data['PEM_login_id']
KeyError: 'PEM_login_id'
>>> post = QueryDict("PEM_login_id=beefsupremexxc&PEM_password=beef1234&PEM_password_confirm=beef123")
>>> f = PEMUserDetailsForm(post)
>>> f.is_valid()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 120, in is_valid
    return self.is_bound and not bool(self.errors)
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 111, in _get_errors
    self.full_clean()
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 243, in full_clean
    value = getattr(self, 'clean_%s' % name)()
  File "/home/niall/public_html/projects/GIBO/dev/projects/signup/gibo/../gibo/deployment/models.py", line 791, in clean_PEM_password_confirm
    p = self.cleaned_data['PEM_password']
KeyError: 'PEM_password'
>>> f.errors
{'PEM_password': [u'Password is based on personal information.']}
>>> 

, но работает так

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from gibo.deployment.models import PEMUserDetailsForm
>>> from django.http import QueryDict
>>> post = QueryDict("PEM_login_id=beefsupreme&PEM_password=beef1234&PEM_password_confirm=beef123")
>>> f = PEMUserDetailsForm(post)
>>> f.errors
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 111, in _get_errors
    self.full_clean()
  File "/usr/lib/pymodules/python2.6/django/forms/forms.py", line 243, in full_clean
    value = getattr(self, 'clean_%s' % name)()
  File "/home/niall/public_html/projects/GIBO/dev/projects/signup/gibo/../gibo/deployment/models.py", line 777, in clean_PEM_password
    login = self.cleaned_data['PEM_login_id']
KeyError: 'PEM_login_id'
>>> f.errors
{'PEM_login_id': [u'This Login ID is already taken, please choose another.']}
>>> f.is_valid()
False
>>> 

Ответы [ 2 ]

3 голосов
/ 11 апреля 2011

Методы очистки, специфичные для поля - clean_PEM_password () и т. Д. - должны обращаться к этому конкретному полю только из self.cleaned_data. Другие поля еще не гарантированы. Если вам необходимо выполнить проверку по нескольким полям, вы должны использовать метод clean (), так как все методы проверки по конкретным полям уже были выполнены.

Очистка и проверка полей, которые зависят друг от друга

0 голосов
/ 11 апреля 2011

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

Таким образом, вы либо находите способ работать без «cleaned_data», либо определяете метод clean (), где вы можете получить доступ к «cleaned_data», а затем написать свою собственную логику проверки и, при необходимости, выдавать ValidationErrors.1004 * Я склонен использовать вариант b в моих собственных проектах, если только я действительно не создаю новый тип поля формы, где требуется пользовательская проверка, особенно при проверке наличия данных в моей базе данных.

...