Создание подкатегорий с помощью jquery ajax при выборе категории в Django

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

Это мой html код

<div class="container pt-5" style="height: 800px !important;">
            <div class="mx-auto" style="width: 500px" ;>
                <form id="form" action="../message/" method="post" name="contactForm" class="form-horizontal" data-subCat-url="{% url 'ajax_load_subCats' %}">
                    {% csrf_token%}
                    <div class="col-xs-8 col-xs-offset-4 mt-5">
                        <h2 style="text-align:center;">Contact</h2>
                    </div>
        
                    <div class="form-group">
                        <label class="p-2" for="title">Title</label>
                        <input type="title" class="form-control" name="text" id="title" placeholder="Enter A Title" required="required">
                    </div>
                    <div class="form-group">
                        <label class="p-2" for="category">Category</label>
                        <select class="form-select" aria-label="Default select example" id="category" required>
                            <option selected>Select a category</option>
                            <option value="theft">Theft</option>
                            <option value="assault">Assault</option>
                            <option value="accident">Accident</option>
                            <option value="fire">Fire</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label class="p-2" for="category">Sub Category</label>
                        <select id="subCat" class="form-select" aria-label="Default select example" required>
                            
                        </select>
                    </div>
                    <div class="form-group">
                        <label class="p-2" for="subject">Subject</label>
                        <textarea type="text" class="form-control" name="subject" cols="30" rows="10" placeholder="Enter Subject" required="required"></textarea>
                    </div>
                    <button type="submit" class="btn btn-primary float-end mt-2">Send</button>
                    <br />
                    <div class="form-group">
                        {% for message in messages %}
                        <div class="alert alert-danger" role="alert">
                            {{message}}
                        </div>
                        {% endfor %}
                    </div>
                </form>
            </div>
        </div>

Я не добавляю html теги, такие как body, head, html. Так что проблема не здесь.

Это мой скрипт Jquery

    $(document).ready(function(){

        $("#category").change(function(){
            const url = $("#form").attr('data-subCat-url');
            const catName = $(this).children("option:selected").val();
            console.log(url)
            console.log(catName)
            $.ajax({
                url: url,
                data: {
                    'cat_name': catName
                },
                success: function(data){
                    $("#subCat").html(data);
                }
            })
        });

    })

Этот файл - models.py :

from django.db import models

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=100)
    def __str__(self):
        return self.name

class subCategory(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE,)
    subName = models.CharField(max_length=100)
    def __str__(self):
        return self.subName

Этот файл - forms.py:

from dataclasses import fields
from pyexpat import model
from unicodedata import category
from django import forms
from .models import subCategory

class subCategoryCreationForm(forms.ModelForm):
    class Meta:
        model = subCategory
        fields = '__all__'
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['subName'].queryset = subCategory.objects.none

        if 'category' in self.data:
            try:
                category_id = int(self.data.get('category'))
                self.fields['subCategory'].queryset = subCategory.objects.filter(category_id=category_id).order_by('name')
            except (ValueError, TypeError):
                pass # invalid form
        elif self.instance.pk:
            self.fields['subCategory'].queryset = self.instance.category.subCategory_set.order_by('name')

Этот файл - views.py:

def loadSubCats(request):
    cat_name = request.GET.get('cat_name')
    categories = Category.objects.all()
    sub_category = subCategory.objects.filter(category_id= categories['id']).all()
    count = subCategory.objects.filter(category_id= categories['id']).count()
    return render(request, 'report/load-sub-cats.html', {'sub_category' : sub_category})

Этот файл - urls.py:

from django.urls import path
from . import views


urlpatterns = [
    path('', views.report, name='report'),
    path('add/', views.add, name='add'),
    path('add/ajax/load-subCats/', views.loadSubCats, name='ajax_load_subCats'),
] 

В заключение, это файл load-sub-cats.html:

<option selected>Select a sub category</option>
<h3>{{count}}</h3>
{% for sub_category in  sub_categories %}
    <option value="{{ sub_category.pk }}">{{ sub_category.subName }}</option>
{% endfor %}

Я кратко объясню вам, что я буду делать здесь. У меня есть html страница для выбора категории пользователем. Когда он выбирает ее, jquery ajax получает данные из этого пути: path('add/ajax/load-subCats/', views.loadSubCats, name='ajax_load_subCats'), на urls.py. Файл load-sub-cats.html - это параметры подкатегории, полученные из views.py. Таким образом, из views.py я буду возвращать подкатегорию о категории, выбранной пользователем.

forms.py & models.py - это просто файлы для создания базы данных. Я думаю, что проблема между файлом views.py и файлом load-sub-cats.html. Вот как выглядит проблема в консоли, когда я выбираю опцию категории :

enter image description here

И вот какая проблема возникает, когда я открываю эту ссылку report/add/ajax/load-subCats/?cat_name=theft :

TypeError at /report/add/ajax/load-subCats/
QuerySet indices must be integers or slices, not str.
Request Method: GET
Request URL:    http://127.0.0.1:8000/report/add/ajax/load-subCats/?cat_name=theft
Django Version: 4.1.1
Exception Type: TypeError
Exception Value:    
QuerySet indices must be integers or slices, not str.
Exception Location: C:\Users\acer\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\query.py, line 414, in __getitem__
Raised during:  report.views.loadSubCats
Python Executable:  C:\Users\acer\AppData\Local\Programs\Python\Python310\python.exe
Python Version: 3.10.7
Python Path:    
['D:\\Connecting_Project\\Python\\ReportingPlatform',
 'C:\\Users\\acer\\AppData\\Local\\Programs\\Python\\Python310\\python310.zip',
 'C:\\Users\\acer\\AppData\\Local\\Programs\\Python\\Python310\\DLLs',
 'C:\\Users\\acer\\AppData\\Local\\Programs\\Python\\Python310\\lib',
 'C:\\Users\\acer\\AppData\\Local\\Programs\\Python\\Python310',
 'C:\\Users\\acer\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages']
Server time:    Tue, 27 Sep 2022 18:31:52 +0000
Traceback Switch to copy-and-paste view
C:\Users\acer\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py, line 55, in inner
                response = get_response(request) …
Local vars
C:\Users\acer\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py, line 197, in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
D:\Connecting_Project\Python\ReportingPlatform\report\views.py, line 21, in loadSubCats
            form.save()
            return redirect('../showAll/')
    return render(request, 'report/add.html')
def loadSubCats(request):
    cat_name = request.GET.get('cat_name')
    categories = Category.objects.all()
    sub_category = subCategory.objects.filter(category_id= categories['id']).all() …
    count = subCategory.objects.filter(category_id= categories['id']).count()
    return render(request, 'report/load-sub-cats.html', {'sub_category' : sub_category})
def showAll(request):
    return render(request, 'report/show-all.html')
Local vars

Большое спасибо за ваше время.

Наконец-то нашел решение. Проблема в том, что при создании поля выбора я использую название категории в значениях опций. Но так делать нельзя. Решение заключается в том, чтобы поместить ID категории в значение опции. Таким образом, при получении данных из базы данных с помощью jquery ajax, ID категории будет отправлен для получения данных.

Вернуться на верх