仅在首次提交时使用django-autocomplete-light尝试“选择有效选项”错误

时间:2016-04-10 17:00:18

标签: django django-forms django-autocomplete-light

我使用django-autocomplete-light得到了这个奇怪的错误:“选择一个有效的选择。这个选择不是可用的选择之一。”但是,如果我停留在同一页面上并再次按下提交,则表示该表单没有问题,并且表单中的数据将按照它应该插入数据库中。

我有一个嵌入式表单,其中包含另一个模型的可添加内联。使用这些模型,我可以在同一个BookSumbission页面上为每个书籍制作一个BookSubmission,其中包含多个不同的书籍(通过ForeignKey指向另一个书籍模型),并为每个书籍指定其数量。

当我没有激活小部件时,一切正常。我可以从预期的列表中选择一本或多本书。 如果激活小部件,一切似乎都可以正常工作,即使小部件显示预期的书籍。但是,如果我按提交,我会收到错误。再次提交提交,表单完美呈现。

有谁知道这里发生了什么?我想也许它与.js文件的加载顺序有关,但玩弄它并没有给我任何无结果的结果。

models.py

class BookSubmission(models.Model):
    SubmissionTitle = models.CharField(
                                     max_length=6,
                                     verbose_name="Submission Title",
                                     unique=True)
    SubmissionText = models.TextField(
                                    max_length=1500,
                                    null=True,
                                    blank=True,
                                    verbose_name="Submission Text"
                                    )


class BooksAndQuantity(models.Model):
    Submission = models.ForeignKey(
                                   'Submission',
                                   null=True,
                                   blank=True,
                                   verbose_name="BookSubmission"
                                   )
    Book = models.ForeignKey(
                                 'Books',
                                 to_field='BookTitle',
                                 db_column='BookTitleID',
                                 null=True,
                                 blank=True,
                                 )
    Quantity = models.FloatField(verbose_name="Quantity")


class Books(models.Model):
    BookTitle = models.CharField(
                                   max_length=6,
                                   unique=True,
                                   db_column='BookTitleID')
    BookText = models.TextField(
                                  max_length=1500,
                                  null=True,
                                  blank=True
                                  )

forms.py

class BookSubmissionForm(forms.ModelForm):
    class Meta:
        model = BookSubmission
        fields = '__all__'

BookAndQuantityFormset = inlineformset_factory(
    BookSubmission,
    BookAndQuantity,
    fields='__all__',
    extra=1,
    widgets={'Book':
             autocomplete.ModelSelect2(url='BookAutocomplete')})

views.py

class BookSubmissionView(generic.CreateView):
    template_name = 'BookSubmission.html'
    model = BookSubmission
    form_class = BookSubmissionForm
    success_url = 'success/'

    def get(self, request, *args, **kwargs):
        """
        Handles GET requests and instantiates blank versions of the form
        and its inline formsets.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        BookAndQuantityForm = BookAndQuantityFormset()
        return self.render_to_response(
            self.get_context_data(form=form,
                                  BookAndQuantityForm=BookAndQuantityForm))

    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance and its inline
        formsets with the passed POST variables and then checking them for
        validity.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        BookAndQuantityForm = BookAndQuantityFormset(self.request.POST)
        if (form.is_valid() and BookAndQuantityForm.is_valid()):
            return self.form_valid(form, BookAndQuantityForm)
        else:
            return self.form_invalid(form, BookAndQuantityForm)

    def form_valid(self, form, BookAndQuantityForm):
        """
        Called if all forms are valid. Creates a Recipe instance along with
        associated Ingredients and Instructions and then redirects to a
        success page.
        """
        self.object = form.save()
        BookAndQuantityForm.instance = self.object
        BookAndQuantityForm.save()
        specieandquantityout_form.instance = self.object
        specieandquantityout_form.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form, BookAndQuantityForm):
        """
        Called if a form is invalid. Re-renders the context data with the
        data-filled forms and errors.
        """
        return self.render_to_response(
            self.get_context_data(form=form,
                                  BookAndQuantityForm=BookAndQuantityForm))


class BookAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        # Don't forget to filter out results depending on the visitor !
        # if not self.request.user.is_authenticated():
        #    return Specie.objects.none()

        qs = Books.objects.all()

        if self.q:
            qs = qs.filter(BookTitle__istartswith=self.q)

        return qs

使用以下html文件:

parent.html

<head>
    {% load staticfiles %}
    <link rel="stylesheet" href="{% static 'personal/css/bootstrap.min.css' %}" type = "text/css"/>
    <link rel="stylesheet" href="{% static 'personal/css/navbar-fixed-top.css' %}" >
    <link rel="stylesheet" href="{% static 'personal/assets/ie10-viewport-bug-workaround.css' %}" >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <meta name="viewport" content = "width=device-width, initial-scale=1.0">
    <script src="{% static 'personal/assets/ie10-viewport-bug-workaround.js' %}"></script>
    <script src="{% static 'personal/js/bootstrap.min.js' %}"></script>

    <style type="text/css">
        html,
        body {
          height:100%
        }
    </style>

</head>

BookSubmission.html

{% extends "parent.html" %}
{% load staticfiles %}

{% block content %}
    <div>
        <h1>Add BookSubmissionForm</h1>
        <form action="" method="post">
            {% csrf_token %}
            <div>
                <p> BookSubmission Title {{ form.SubmissionTitle }} </p>
                <p> BookSubmission Text {{ form.SubmissionText }} </p>
            </div>
            <fieldset>
                <legend>Book and Quantity</legend>
                {{ bookandquantity_form.management_form }}
                {{ bookandquantity_form.non_form_errors }}
                {% for form in bookandquantity_form %}
                    {{ form.id }}

                    <div class="inline {{ bookandquantity_form.prefix }}">
                        {{ form.Book.errors }}
                        {{ form.Book.label_tag }}
                        {{ form.Book }}
                        {{ form.Quantity.errors }}
                        {{ form.Quantity.label_tag }}
                        {{ form.Quantity }}
                    </div>
                {{ form.media }}
                {% endfor %}
            </fieldset>
            <input type="submit" value="Add BookSubmission" class="submit" />
        </form>
    </div>

{% endblock %}

{% block footerContent %}
    <script src="{% static 'MM/js/jquery.formset.js' %}"></script>
    <script type="text/javascript">
        $(function() {
            $(".inline.{{ bookandquantity_form.prefix }}").formset({
                prefix: "{{ bookandquantity_form.prefix }}",
            })
        })
    </script>
{% endblock %}

urls.py

url(r'^BookAutoComplete/$',
    views.BookAutoComplete.as_view(),
    name='BookAutoComplete'),

修改

还有什么奇怪的是以下内容,我第一次在其看起来有问题的形式中推送“添加另一个”。 在下图中,相同的Formset被插入两次(现在名为“Species and Quanity”In&amp; Out)。

“物种和数量输入”的描述没有点击“添加另一个” 在“物种和数量输出”中,我点击了“添加另一个”,你可以看到第一行变成了错误,在第二行中添加了一个空白的无用字段。

screenshot

1 个答案:

答案 0 :(得分:0)

您的表单验证代码错误,这就是表单无法验证的原因。

如果有疑问,请尝试不使用自动填充小部件。

有关详细信息,请参阅Django forms documentation