使用 Ajax 动态更新 Django 表单字段选项以获取新的查询集

Luc*_*wds 6 javascript django ajax django-forms

我是编码和 django 的新手,在查看了我找到的答案后,我正在努力寻找以下问题的解决方案。

我正在创建一个包含多个字段的搜索表单。当用户选择第一个字段category(并且在点击搜索之前)时,我想动态更改第二个字段的查询集sub_category,以便仅显示相关值。

我有models.py如下:

class Product(models.Model):
    category = models.ForeignKey("Category")
    sub_category = models.ForeignKey("SubCategory")

class Category(models.Model):
    name = models.CharField(max_length=256)

class SubCategory(models.Model):
    category = models.ForeignKey("Category")
    name = models.CharField(max_length=256)
Run Code Online (Sandbox Code Playgroud)

我的forms.py包括:

class BasicSearchForm(forms.Form):
    category = forms.ModelChoiceField(
        label='Category',
        queryset=Category.objects.all(),
        to_field_name="name",
        empty_label=None,
        initial="Red") 
    sub_category = forms.ModelMultipleChoiceField(
        required=False,
        label='Type',
        queryset= SubCategory.objects.all(),
        to_field_name="name",
        widget=forms.Select)
Run Code Online (Sandbox Code Playgroud)

我的views.py包括:

def search(request):
    if request.method == 'POST':
        form = BasicSearchForm(request.POST)
        if form.is_valid():
            category = form.cleaned_data['category']
            sub_category = form.cleaned_data['sub_category']
            return render(request, 'myapp/search.html', {'form': form})
    else:
        form = BasicSearchForm()
        return render(request, 'myapp/search.html', {'form': form})
Run Code Online (Sandbox Code Playgroud)

最后 search.html 包括:

<form class="search-form" role="search" action="/search/" method="get"> 
    {{ form }} 
    <input type="submit" value="Search" />
</form>
Run Code Online (Sandbox Code Playgroud)

我玩过一些答案,但似乎没有任何效果。我真的很感激一些帮助。提前致谢!

更新: 感谢您的反馈。结果我更新了以下内容:

在我的urls.py

urlpatterns = [
url(r'^ajax/update_subcategories/$', views.update_subcategories, name='update_subcategories'),
Run Code Online (Sandbox Code Playgroud)

而在我的views.py

def update_subcategories(request):
    category = request.GET.get('category', None)
    sub_category = list(SubCategory.objects.filter(category__name__exact=category).values('name'))
    return JsonResponse(sub_category, safe=False)
Run Code Online (Sandbox Code Playgroud)

我有这个myapp/search.html

{% block javascript %}
<script>
    $("#id_category").change(function () {
        var category = $(this).val();
        $.ajax({
            url: '{% url "myapp:update_subcategories" %}',
            data: {
                'category': category,
            },
            success: function (response) {
                var  new_options = response; 
                alert(new_options[0].name);  // works
                $('#id_sub_category').empty();
                $.each(new_options, function(key, value) {   
                    $('#id_sub_category')
                        .append($('<option>', { value : key })
                        .text(value.name)); 
                });
            }
    });
</script>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

更新:sub_category 选项一直显示为 [object Object],直到我将 value 更改为 value.name 并且看起来它正在工作。除非有任何评论,否则我将对其进行测试并关闭。

更新:我仍然遇到浏览器后退按钮的问题。当用户单击返回时,下拉值已更改回原始查询集而不是更新版本。

zai*_*zil 3

你不能从 Django 视图端(即后端)执行此操作。您可以尝试使用 ajax 请求来实现此类请求,方法是向服务器发送 GET 请求以填充下拉列表或您想要的任何内容。

一个简单的例子,你可以参考这里

如何在 Django 中使用 jQuery/Ajax 进行 POST?

编辑

def update_subcategories(request):
    category = request.GET.get('category', None)
    sub_category = list(SubCategory.objects.filter(category__name__exact=category).values('name'))
    return JsonResponse(dict(sub_category=sub_category))
Run Code Online (Sandbox Code Playgroud)

然后在ajax响应中你可以像这样抓住它response.data.sub_category