Обновление набора запросов Django ModelMultipleChoiceField в конструкторе завершается неудачно на POST - PullRequest
1 голос
/ 07 января 2011

Я пытался выяснить, как работать с ModelMultipleChoiceFields в форме, из различных вопросов о StackOverflow.У меня почти есть рабочая форма, которая позволяет пользователям выбирать языки для перевода статьи.Я создал форму, которая принимает SourceArticle в качестве первого аргумента конструктора и использует ее для указания набора запросов для поля languages моей формы.

class AddTargetLanguagesForm(forms.Form):
    def __init__(self, article=None, *args, **kwargs):
    super(AddTargetLanguagesForm, self).__init__(*args, **kwargs)
    self.fields['languages'].queryset = Language.objects.exclude(
                        Q(id = article.language.id) |
                        Q(id__in=[o.id for o in article.get_target_languages()]) |
                        Q(code="templates"))

    languages = forms.ModelMultipleChoiceField(_("Languages"))

Обратите внимание, что мой AddTargetLanguagesForm не основанна ModelForm, поскольку он не имеет прямого отношения ни к одному из моих объектов модели.

Когда я впервые отображаю форму, он правильно предоставляет мне языки, которые (а) не являются источникомязык, (b) еще не выбран, и (c) не являются специальным языком шаблонов.Однако, когда я пытаюсь опубликовать свою форму, я получаю следующую ошибку:

AttributeError: у объекта 'QueryDict' нет атрибута 'language'

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

Вот копия моего представления, если оно поможет вам понять, как я использую форму.

@login_required
def add_target_languages(request, aid, template_name="wt_articles/add_target_languages.html"):
    """
    Adds one or more target language translations to a source article. 
    """
    content_dict = {}

    # Fetch the article
    no_match = False

    sa_set = SourceArticle.objects.filter(id=aid)
    if len(sa_set) < 1:
        no_match = True
        content_dict['no_match'] = no_match
    else:
        article = sa_set[0]
        content_dict['article'] = article

        if request.method == "POST":
            target_language_form = AddTargetLanguagesForm(request.POST)

            if target_language_form.is_valid():
                languages = target_language_form.cleaned_data['languages']

                article.add_target_languages(languages)
                return HttpResponseRedirect('/articles/list')
        else:
            target_language_form = AddTargetLanguagesForm(article)

        content_dict['target_language_form'] = target_language_form
    return render_to_response(template_name, content_dict, 
                              context_instance=RequestContext(request))

1 Ответ

3 голосов
/ 07 января 2011

Эта строка - ваша проблема:

target_language_form = AddTargetLanguagesForm(request.POST)

Это стандартный способ создания формы из POST, но проблема в том, что вы переписали сигнатуру метода AddTargetLanguagesForm.__init__:

def __init__(self, article=None, *args, **kwargs):

так, чтобы первый позиционный аргумент (после автоматического self), был article. Вы могли бы изменить экземпляр, но я предпочитаю делать это:

def __init__(self, *args, **kwargs):
    article = kwargs.pop('article', None)
    super(AddTargetLanguagesForm, self).__init__(*args, **kwargs)
    if article is not None:
        ...etc...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...