我正在尝试实现一个依赖下拉列表。 Vitor Freitas在他的博客中做了这个,我基本上是在关注他的solution。 (一个非常酷的博客,提供了清晰的代码,这对我很有帮助。)
我在页面上采用了它,但是它恰好卡在应该限制下拉列表的位置。
我很确定我弄混了外键或Ajax / javascript(因为我不了解ajax + javascript。)也许您看到了我的“基本”错误,可以为我提供帮助。会很感激的。
models.py
class Country(models.Model):
name = models.CharField(max_length=3)
def __str__(self):
return self.name
class Provider(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class CustomerSubsidiary(models.Model):
subCountry = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
subName = models.CharField(max_length=50, blank=True)
urls.py
urlpatterns = [
path('test', views.CustomerSubsidiaryListView.as_view(), name='CustomerSubsidiary_changelist'),
path('test/add/', views.CustomerSubsidiaryCreateView.as_view(), name='CustomerSubsidiary_add'),
path('test/<int:pk>/', views.CustomerSubsidiaryUpdateView.as_view(), name='CustomerSubsidiary_change'),
path('ajax/load-provider/', views.load_provider, name='ajax_load_provider'),
]
views.py
def load_provider(request):
country_id = request.GET.get('country')
provider = Provider.objects.filter(country_id=country_id).order_by('name')
return render(request, 'Customer/city_dropdown_list_options.html', {'provider': provider})
providerForm
class ProviderForm(forms.ModelForm):
class Meta:
model = CustomerSubsidiary
fields = ('subName', 'subCountry', 'provider')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['provider'].queryset = Provider.objects.none()
customersubsidiary_form.html
{% extends 'base.html' %}
{% block content %}
<h2>Provider Form</h2>
<form method="post" id="providerForm" data-provider-url="{% url 'ajax_load_provider' %}" novalidate>
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button type="submit">Save</button>
<a href="{% url 'CustomerSubsidiary_changelist' %}">Nevermind</a>
</form>
<script>
$("#id_country").change(function () {
var url = $("#providerForm").attr("data-provider-url");
var countryId = $(this).val();
$.ajax({
url: url,
data: {
'country': countryId
},
success: function (data) {
$("#id_provider").html(data);
}
});
});
</script>
{% endblock %}
jquery已加载到base.html中。
city_dropdown_list_options.html
<option value="">-------</option>
{% for providers in provider %}
<option value="{{ providers.pk }}">{{ providers.name }}</option>
{% endfor %}
答案 0 :(得分:0)
我在页面的源代码中看到ID的名称错误,这意味着它们与views.py不匹配。
在 views.py 中应该是:
def load_provider(request):
country_id = request.GET.get('subCountry') #<-- change country to subCountry, that means the attribute name of the original class
在 ajax脚本中,将ID更改为#id_subCountry,将国家/地区更改为subCountry:
<script>
$("#id_subCountry").change(function () {
var url = $("#providerForm").attr("data-provider-url"); // get the url of the `load_cities` view
var subCountryId = $(this).val(); // get the selected country ID from the HTML input
$.ajax({ // initialize an AJAX request
url: url, // set the url of the request (= localhost:8000/hr/ajax/load-cities/)
data: {
'subCountry': subCountryId // add the country id to the GET parameters
},
success: function (data) { // `data` is the return of the `load_cities` view function
$("#id_provider").html(data); // replace the contents of the city input with the data that came from the server
}
});
});
</script>
答案 1 :(得分:0)
此处的问题:self.fields ['provider']。queryset = Provider.objects。无()。当您在表单字段“ provider”中从“ request.POST”添加数据时,将始终为“ none”。尝试从代码中删除此行或添加它:
views.py/edit
if request.method == "POST":
ProviderForm.request_change=True
form = ProviderForm(request.POST)
forms.py
class ProviderForm(forms.ModelForm):
request_change=False
class Meta:
model = CustomerSubsidiary
fields = ('subName', 'subCountry', 'provider')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if request_change:
request_change=False
else:
self.fields['provider'].queryset = Provider.objects.none()