Создание подкатегорий с помощью 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. Вот как выглядит проблема в консоли, когда я выбираю опцию категории :
И вот какая проблема возникает, когда я открываю эту ссылку 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 категории будет отправлен для получения данных.