динамически фильтруемая форма django - PullRequest
2 голосов
/ 20 декабря 2011

Я конвертирую проект из php в Django и столкнулся с проблемой отфильтрованных меню.У меня есть форма:

class SearchForm(forms.Form):
    genus = forms.CharField(max_length=100)
    #    species
    species = forms.CharField(max_length=100)
    #   island group
    island_group = forms.ModelChoiceField(queryset=Localitymayor.objects.values_list('islandgroup', flat=True).distinct('islandgroup').exclude(islandgroup="n/a").order_by('islandgroup'), empty_label=_("Not Specified"))
    #   island name
    island_name = forms.ModelChoiceField(queryset=Localitymayor.objects.values_list('islandname', flat=True).distinct('islandname').exclude(islandname="n/a").order_by('islandname'), empty_label=_("Not Specified"))

мой шаблон выглядит следующим образом:

<form action="{% url cdrs_search %}" method="post">{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
    {{ field.errors }}
    {{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
</form>

Теперь я хочу отфильтровать вывод island_name в зависимости от выбора island_group.В моем проекте php я справился с этим с помощью вызова ajax onChange для другого сценария php.Тем не менее, я немного растерялся, как это сделать в Джанго.Поскольку я впервые работаю с ajax в Django, я был бы признателен за любые предложения относительно наилучшего практического способа решения этой простой, но распространенной проблемы с отфильтрованным меню.Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 20 декабря 2011

Один из вариантов - сделать это в JavaScript. Вы можете позвонить в отдельное представление, используя ajax-запрос из jQuery . Работа этого отдельного представления заключается в том, чтобы обрабатывать на стороне сервера имя модели (острова) данных вашей модели на основе выбранной группы island_group). Затем вы можете использовать javascript для повторного заполнения ваших форм, используя ответ от представления. Некоторые хорошие примеры того, как это сделать, можно найти в этом блоге (он немного плотный, но очень полезный), в статье о том, как это сделать с помощью javascript , и в этом уроке (настоятельно рекомендуется).

Существует также хороший пост SO, который объясняет, почему это необходимо делать таким образом, его может быть немного педантично, но он помог мне прояснить ситуацию при создании отфильтрованных форм. Просто посмотрите на принятый ответ на этот вопрос.

1 голос
/ 20 декабря 2011

вам нужно иметь представление о вашем скрипте ajax, чтобы запросить список имен на основе группы, например,

# views.py
def ajax_endpoint(request):
    # leaving error checking to you
    group = request.GET.get('group')
    names_list = avalable_names(group) # some function or db call
    return HttpResponse(json.dumps(names_list))
0 голосов
/ 21 декабря 2011

Здесь приведена модификация кода из формы билета betspire.com. Этот фрагмент кода зависит от загрузки jQuery.

Вот необходимый вам javascript:

    function update_select(select, data) {
        select.find('option').remove();
        select.append($('<option value="">-------</option>'));
        for (var i in data) {
            select.append($('<option value="'+data[i][0]+'">'+data[i][1]+'</option>'));
        }
    }

    $('select[name=island_group]').live('change', function(e) {
        $.get(
            '{% url island_name_choices_for_island_group %}',
            {
                'island_group': $(this).val(),
            },
            function(data, textStatus, jqXHR) {
                update_select($('select[name=island_name]'), data);
            },
            'json'
        );
    });

Добавить к URL:

url(
    r'island_name/choices/$',
    'island_name_choices_for_island_group', {
    }, 'island_name_choices_for_island_group',
),

Добавить в просмотры:

from django.utils import simplejson

from models import *

def island_name_choices_for_island_group(request, qs=None):
    if qs is None:
        # Change the default QS to your needs
        # (you didn't specify it)
        qs = Island.objects.all()

    if request.GET.get('island_group'):
        # assuming your Island model has an FK named island_group to model IslandGroup
        qs = qs.filter(island_group__pk=request.GET.get('island_group'))

    results = []
    for choice in qs:
        results.append((choice.pk, choice.name))

    return http.HttpResponse(simplejson.dumps(results))

Пожалуйста, дайте мне знать, если у вас возникнут какие-либо проблемы.

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