Свет автозаполнения Django - результаты полей FK не пересылаются

Я следую в документации DAL, чтобы добавить отфильтрованное поле в мою форму, но переадресация не работает для соединения одного поля с другим:

Forms.py

class PurchaseForm(forms.ModelForm):

    commodity = forms.ModelChoiceField(
        queryset=Commodity.objects.all(),
        widget=autocomplete.ModelSelect2(url='commodity-autocomplete'),
        required=False,
    )

    class Meta:
        model = Purchase
        fields = ["variety"]
        widgets = {
            'variety': autocomplete.ModelSelect2(url='variety-autocomplete', forward=['commodity'],   
        }

Views.py

class VarietyAutocompleteView(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = Variety.objects.all()

        commodity = self.forwarded.get('commodity', None)
        print("Commodity:" + str(commodity))
        if commodity:
            qs = qs.filter(commodity=commodity)

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

        return qs

Я бы хотел, чтобы мои варианты Variety были отфильтрованы по их связи внешнего ключа с объектами Commodity. Оба поля автозаполнения работают сами по себе просто отлично, но выбор из commodity поле не пересылается в VarietyAutocompleteView (моя команда print печатает Commodity:None). Возможно, это потому, что я передаю объект внешнего ключа? Или я как-то неправильно это настроил?

2 ответа

Решение

Мне пришлось отказаться от DAL и перейти к Bootstrap Combobox. Это оказалось очень легко реализовать, если вы используете библиотеки Bootstrap.

Вот как это настроено:

Добавить класс combobox для выбора виджета:

forms.py

from django import forms

from Business.models import Company, Branch
from .models import Variety

class PurchaseForm(forms.ModelForm):

    variety = forms.ModelChoiceField(
        queryset=Variety.objects.all(),
        widget=forms.Select(attrs={'class': 'combobox'}),
        required=False
    )

    class Meta:
        model = Purchase
        fields = [
            "invoice", "contract_date", ...
        ]

Затем вставьте самый простой фрагмент кода JavaScript:

inventory_report.html

....

<td style="padding-bottom: 10px">
    <div>Supplier:</div>
    <div>{{ view.purchase_form.supplier }}</div>
</td>

....
{% block scripts %}
    <script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
    <script type="text/javascript" src="{% static 'js/bootstrap-combobox.js' %}"></script>

        $(document).ready(function(){

            // Set Text Autofields on New Contract
           $('.combobox').combobox();

        });

    </script>
    {{ view.purchase_form.media }}
{% endblock %}

Это все, что нужно сделать.

Добавлю для всех, кто думает "ага, но я все еще очень не хочу меняться" - что на практике строчка:

       'variety': autocomplete.ModelSelect2(url='variety-autocomplete', forward=['commodity'])

На самом деле у меня тоже не сработало, но я изменил его на что-то вроде:

       'variety': autocomplete.ModelSelect2(url='variety-autocomplete', forward=('commodity', ))

Работал. Обратите внимание, что это кортеж, поэтому вам нужно иметь «,», чтобы он работал, поскольку он должен быть итерируемым значением.

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

Кроме того, я использовал набор форм (поэтому были префиксы), и это не было проблемой.

Другие вопросы по тегам