user14771414
user14771414

Reputation:

Create sub category using jquery ajax when selecting a category in Django

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 :

enter image description here

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

Answers (1)

user14771414
user14771414

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

Related Questions