Цепочка выпадающих элементов в ModelFormset_Factory - Django
Я хочу иметь цепочку выпадающих списков в наборе форм модели.
В моем приложении App_Prod есть 4 модели - Category, Product, OrderInfo, Order
.
В моей форме я использовал два представления вместе. OrderInfo и Order
.
Поэтому список выбора поля product модели Order должен зависеть от поля category модели OrderInfo. Например, если я выбираю категорию Electronics, список выбора должен возвращать только laptop и mobile, а не показывать все варианты. Для лучшего понимания смотрите изображение.
.
Пожалуйста, подскажите, что мне нужно изменить в коде, или есть ли другой способ сделать это.
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.IntegerField()
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
def __str__(self):
return self.name
class OrderInfo(models.Model):
category = models.ForeignKey(Category, related_name='orderInfo', on_delete=models.CASCADE)
date = models.DateField()
def __str__(self):
return self.category.name
class Order(models.Model):
info = models.ForeignKey(OrderInfo, related_name='orders', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='productName', on_delete=models.CASCADE, null=True)
quantity = models.IntegerField()
def __str__(self):
return self.product.name
forms.py
class OrderInfoForm(forms.ModelForm):
date = forms.DateField(widget=DateInput)
class Meta:
model = OrderInfo
fields = ["category","date",]
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ["product","quantity",]
widgets = {
'product': forms.Select(attrs={'class': 'formset-field form-control'}),
'quantity': forms.NumberInput(attrs={'class': 'formset-field form-control'}),
}
views.py
def order_create(request):
context = {}
OrderFormset = modelformset_factory(Order, form=OrderForm)
form = OrderInfoForm(request.POST or None)
formset = OrderFormset(request.POST or None, queryset=Order.objects.none(), prefix='productName')
if request.method == "POST":
if form.is_valid() and formset.is_valid():
try:
with transaction.atomic():
info = form.save(commit=False)
info.save()
for order in formset:
data = order.save(commit=False)
data.info = info
data.save()
except IntegrityError:
print("Error Encountered")
return redirect('App_Prod:order_create')
context['formset'] = formset
context['form'] = form
return render(request, 'App_Prod/order_create.html', context)
urls.py
urlpatterns = [
path('create/', views.order_create, name="order_create"),
]
order_create.html
<!DOCTYPE html>
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block body_block %}
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
<table class="table form-table table-bordered table-sm">
<thead class="text-center">
<tr>
<th>Product</th>
<th>Quantity</th>
<th></th>
</tr>
</thead>
<tbody>
{% for form_data in formset %}
<tr class="item">
<td>
{{ form_data.product }}
</td>
<td>
{{ form_data.quantity }}
</td>
<td>
<button type="button" class="btn btn-danger btn-sm remove-form-row"
id="{{ formset.prefix }}">
Delete
</button>
</td>
</tr>
{% endfor %}
<tr>
<td colspan="9"
style="border-left: none!important; border-right: none !important; border-bottom: none!important;">
<button type="button" class="btn btn-sm btn-success add-form-row"
id="{{ formset.prefix }}">
Add Activity
</button>
</td>
</tr>
</tbody>
</table>
{{ formset.management_form }}
<button class="btn btn-info" type="submit">Submit</button>
</form>
{% endblock %}
{% block extra_script %}
<script type="text/javascript" src="{% static 'js/formset.js' %}"></script>
{% endblock%}