2011-12-20 3 views
2

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

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-скрипт. Тем не менее, я немного потерял, как это сделать в Django. Поскольку это мой первый опыт работы с ajax в Django, я был бы признателен за любые предложения относительно наилучшего способа решения этой простой, но распространенной проблемы с фильтрованным меню. Заранее спасибо.

+0

Почему в Django это должно быть иначе? Вам все еще нужна функция Ajax onChange, вызывающая вид на стороне сервера. –

ответ

0

Здесь представлена ​​модификация кода из формы билета 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' 
     ); 
    }); 

Добавить в URLs:

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)) 

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

+0

Привет, Я пробовал свой код с некоторыми изменениями, но я все еще не могу получить обновление для ajax. В частности, я не уверен в своем html. Могу ли я отправить вам код, который у меня есть для вас? –

+0

Во-первых: есть ли какая-либо ошибка python в представлении ajax (проверьте вид ajax, открыв URL-адрес или используйте firebug)? Во-вторых: есть ли ошибка javascript (используйте firebug)? В-третьих: добавьте инструкции «console.log» или используйте firebug для отладки javascript и проверьте, что ожидаемый код запускается с ожидаемыми параметрами :) – jpic

+0

Хорошо - я получил его сейчас. Хотя я все еще неясен о 'qs = None', но. Не могли бы вы объяснить, почему это необходимо? –

1

вам нужно, чтобы ваш сценарий 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)) 
1

Один из вариантов - сделать это в javascript. Вы можете сделать вызов для отдельного просмотра, используя запрос ajax от jQuery. Задачей этого отдельного представления является обработка сортировки имени вашей модели (острова) на стороне сервера на основе выбранной пользователем island_group). Затем вы можете использовать javascript для повторного заполнения форм, используя ответ из представления. Несколько хороших примеров того, как это сделать, можно найти: in this blog (немного плотный, но очень полезный), in an article on how to do this with javascript и in this tutorial (очень рекомендуется).

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

+0

Спасибо за ценную информацию. Я посмотрю, смогу ли я заставить это работать для меня. –