Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

To implement a drop-down menu based on Ajax in the Django admin interface, you can follow these steps:

  1. Create a Django model that contains the data for the drop-down menu.

  2. Implement an Ajax view in Django that returns the data for the drop-down menu in JSON format.

  3. Create a form in Django that includes the drop-down menu field and uses an Ajax request to populate the menu options dynamically.

  4. Override the default admin form for your model and replace it with your custom form.

  5. Update the admin page template to include the necessary JavaScript code to make the Ajax request and update the drop-down menu options.

Here's some sample code that can help you implement an Ajax-based drop-down menu in the Django admin interface:

First, create a Django model to store the data for your drop-down menu. For example, let's say you want to create a drop-down menu of products that belong to a particular category:

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

class Product(models.Model):
    name = models.CharField(max_length=50)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

Next, create an Ajax view that returns the list of products for a given category:

from django.http import JsonResponse

def products_by_category(request):
    category_id = request.GET['category_id']
    products = Product.objects.filter(category_id=category_id)
    data = [{'id': p.id, 'name': p.name} for p in products]
    return JsonResponse(data, safe=False)

Now, create a form in Django that includes the drop-down menu field and uses an Ajax request to populate the menu options dynamically:

from django import forms
from django.urls import reverse

class ProductForm(forms.ModelForm):
    category = forms.ModelChoiceField(queryset=Category.objects.all())

    class Media:
        js = ('product_form.js',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['category'].widget.attrs['onchange'] = 'load_products()'

    class Meta:
        model = Product
        fields = '__all__'

Here, we're using the Media inner class to include a JavaScript file called product_form.js that will handle the Ajax request and update the drop-down menu options. We're also adding an onchange event handler to the drop-down menu widget to call the load_products function when the category selection changes.

Now, create the product_form.js file in your static directory and add the following code:

function load_products() {
    var category_id = document.getElementById('id_category').value;
    var url = '/ajax/products_by_category/?category_id=' + category_id;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var options = JSON.parse(this.responseText);
            var select = document.getElementById('id_product');
            select.innerHTML = '';
            options.forEach(function(option) {
                var el = document.createElement('option');
                el.value = option.id;
                el.text = option.name;
                select.appendChild(el);
            });
        }
    };
    xhr.open('GET', url, true);
    xhr.send();
}

This code creates an Ajax request to the products_by_category view with the selected category ID as a query parameter. When the response is received, it updates the options in the drop-down menu for the product field.

Finally, override the default admin form for your model and replace it with your custom form:

class ProductAdmin(admin.ModelAdmin):
    form = ProductForm

admin.site.register(Product, ProductAdmin)

That's it! Now, when you edit a product in the Django admin interface, you'll see a drop-down menu for the category field that dynamically loads the available products based on the selected category.