Проверка ModelChoiceField в формах Django - PullRequest
1 голос
/ 08 марта 2010

Я пытаюсь проверить форму, содержащую ModelChoiceField:

forms.py:

from django import forms

from modelchoicetest.models import SomeObject

class SomeObjectAddForm(forms.ModelForm):
    class Meta:
        model = SomeObject

models.py:

from django.db import models

class SomeChoice(models.Model):
    name = models.CharField(max_length=16)

    def __unicode__(self):
        return self.name

class SomeObject(models.Model):
    choice = models.ForeignKey(SomeChoice)

views.py:

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from forms import SomeObjectAddForm

def add(request):
    if request.method == 'POST':
        form = SomeObjectAddForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('modelchoicetest_add'))
    else:
        form = SomeObjectAddForm()

    return render_to_response('modelchoicetest/index.html',
                              {'form': form},
                              context_instance=RequestContext(request))

Когда он используется в нормальных условиях, все идет хорошо. Но я бы хотел защитить форму от неверного ввода. Совершенно очевидно, что я должен получить forms.ValidationError, когда я помещаю недопустимое значение в это поле, не так ли? Но если я попытаюсь отправить форму со значением «invalid» в поле «somechoice», я получу

ValueError: invalid literal for int() with base 10: 'invalid'

, а не ожидаемые формы. ValidationError. Что я должен делать? Я попытался поместить def clean_somechoice(self), чтобы проверить это поле, но это не сработало: ValueError происходит до до clean_somechoice()

Плюс я не думаю, что это хорошее решение, должно быть что-то более простое, но я просто упустил это.

вот полный ответ:

Traceback:
File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
  101.                     response = callback(request, *callback_args, **callback_kwargs)
File "/home/andrey/public_html/example/modelchoicetest/views.py" in add
  11.         if form.is_valid():
File "/usr/local/lib/python2.6/dist-packages/django/forms/forms.py" in is_valid
  120.         return self.is_bound and not bool(self.errors)
File "/usr/local/lib/python2.6/dist-packages/django/forms/forms.py" in _get_errors
  111.             self.full_clean()
File "/usr/local/lib/python2.6/dist-packages/django/forms/forms.py" in full_clean
  276.                     value = field.clean(value)
File "/usr/local/lib/python2.6/dist-packages/django/forms/fields.py" in clean
  154.         value = self.to_python(value)
File "/usr/local/lib/python2.6/dist-packages/django/forms/models.py" in to_python
  911.             value = self.queryset.get(**{key: value})
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py" in get
  330.         clone = self.filter(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py" in filter
  536.         return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py" in _filter_or_exclude
  554.             clone.query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py" in add_q
  1109.                             can_reuse=used_aliases)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py" in add_filter
  1048.                 connector)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/where.py" in add
  66.             value = obj.prepare(lookup_type, value)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/where.py" in prepare
  267.             return self.field.get_prep_lookup(lookup_type, value)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py" in get_prep_lookup
  314.             return self.get_prep_value(value)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py" in get_prep_value
  496.         return int(value)

Exception Type: ValueError at /
Exception Value: invalid literal for int() with base 10: 'invalid'

Ответы [ 2 ]

1 голос
/ 08 марта 2010

Мне кажется, что исключение вызывается методом clean фактического объекта ModelChoiceField. Поскольку это внешний ключ, Django ожидает int, который будет представлять pk для SomeChoice. Как именно вы передаете invalid в форму?

ОТВЕТ НА КОММЕНТАРИЙ

Если вы действительно чувствуете, что вам нужно это перехватить, вы можете попробовать переопределить стандартное ModelChoiceField, создав новое поле с именем choice и передать to_field_name kwarg в метод ModelChoiceField __init__. Таким образом, Django не будет фильтровать pk и не будет вызывать это исключение.

Лично я бы не использовал это решение. Нет необходимости размещать пользователя, который взламывает вашу форму.

0 голосов
/ 26 октября 2010

Это известная ошибка Джанго:

http://code.djangoproject.com/ticket/11716

И хотя эта ошибка не устранена, вы можете обрабатывать ValueError только вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...