Я реализую цепочечный зависимый выбор комбинированного списка, поэтому вы начинаете с одного комбинированного списка для основной категории, а после выбора основной категории появляется другая <select>
для выбора подкатегории и т. Д., Пока не будет выбрана самая внутренняя (наиболее конкретная) подкатегория. .
В настоящее время это работает следующим образом: всякий раз, когда значение изменяется в выпадающем списке, запускается запрос AJAX, который вызывает представление, которое отображает другой <select>
, если у категории есть дочерние элементы, в противном случае возвращается HttpResponse, который прекращает присоединениеслушатель. Я использую django-mptt
для моделирования своих категорий.
Итак, у меня есть представление о добавлении товаров, и я хочу убедиться, что выбрана наиболее конкретная подкатегория (это должен быть конечный узел), и назначить этоКатегория для моего экземпляра продукта.
Вот вид:
@login_required
def product_create_view(request):
if request.method == 'POST':
create_product_form = CreateProductForm(request.POST)
else:
create_product_form = CreateProductForm()
return render(request, 'products/product_create.html', {'form': create_product_form})
Вот форма:
from django.forms import ModelForm
from .models import Product, Category
class CreateProductForm(ModelForm):
class Meta:
model = Product
fields = (
'title',
'description',
'price',
'year',
'category',
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['category'].queryset = Category.objects.filter(parent=None)
Вот products/product_create.html
:
{% extends 'pages/base.html' %}
{% block content %}
<h1>Create a product</h1>
<form method='POST' id='productForm' data-products-url="{% url 'products:ajax_load_categories' %}">
<label>Title</label>
{{ form.title }}
<label>Description</label>
{{ form.description }}
<label>Price</label>
{{ form.price }}
<label>Year</label>
{{ form.year }}
<label>Category</label>
{{ form.category }}
</form>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
var $r_ = function() {
var url = $("#productForm").attr("data-products-url");
var categoryId = $(this).val();
var toRemove = $(this).nextAll('select');
$.ajax({
url: url,
data: {
'category': categoryId
},
success: function (data) {
if (data != 'leaf_node') {
toRemove.remove();
$("#productForm").append(data);
}
else {
toRemove.remove();
}
}
});
} //end of $r_
$(document).on('change', 'select', $r_);
</script>
{% endblock %}
Вот вид ajax_load_categories
:
def load_categories(request):
category_id = request.GET.get('category')
subcategories = Category.objects.get(id=category_id).get_children()
if subcategories:
return render(request, 'products/category_dropdown_list_options.html', {'subcategories': subcategories})
return HttpResponse('leaf_node')
products/category_dropdown_list_options.html
:
<select>
<option value="">---------</option>
{% for subcategory in subcategories %}
<option value="{{ subcategory.pk }}">{{ subcategory.name }}</option>
{% endfor %}
</select>