Reputation:
I have a problem that when I select a category, sub categories are not showing or showing default option only. I want to show sub-categories about what the user category selected.
This is my html code
<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>
I didn't add html tags like body, head, html, so the problem is not there.
This is my Jquery script
$(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);
}
})
});
})
This file is 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
This file is 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')
This file is 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})
This file is 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'),
]
And finally, this is load-sub-cats.html file:
<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 %}
I have html page to select category from user. When he select it jquery ajax get data from this path : path('add/ajax/load-subCats/', views.loadSubCats, name='ajax_load_subCats')
, on urls.py. File load-sub-cats.html file are the options of sub-category got from views.py
So from views.py I will return sub_category about the category selected from user.
Forms.py & models.py are just files to create database. I think the problem is between views.py file and load-sub-cats.html file. This is the problem showing on console, when I selected a category option :
And this is the problem showing, when I open this link 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
Upvotes: 0
Views: 582
Reputation:
Finally got the solution. The problem is with creating a select box, I'm using the Category name in its option values. But you cannot do this. The solution is to put the Category ID on the options value. So when getting data from database using jquery ajax, Category ID is sent to get data.
Upvotes: 0