我想创建一个客户端,根据 3 种不同的模型选择国家、省、市:
class Country(models.Model):
Country = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.Country
class Province(models.Model):
province = models.CharField(max_length=100, unique=True)
Country = models.ForeignKey(Country, on_delete=models.CASCADE, related_name='province', null=True)
def __str__(self):
return self.province
class City(models.Model):
city = models.CharField(max_length=100, unique=True)
Province = models.ForeignKey(Province, on_delete=models.CASCADE, related_name='city', null=True)
def __str__(self):
return self.city
当用户选择一个国家时,省份列表会更新为国家的省份和城市。
我为此创建 url 并在我的 views.py 中编写代码:
class GetProvincesView(View):
def get(self, request, *args, **kwargs):
country_id = request.GET.get('country_id')
provinces = Province.objects.filter(Country_id=country_id)
data = [{'id': province.id, 'name': province.province} for province in provinces]
return JsonResponse(data, safe=False)
class GetCitiesView(View):
def get(self, request, *args, **kwargs):
province_id = request.GET.get('province_id')
cities = City.objects.filter(Province_id=province_id)
data = [{'id': city.id, 'name': city.city} for city in cities]
return JsonResponse(data, safe=False)
我的模板是:
<!DOCTYPE html>
<html lang="fr">
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h2>Ajouter un client</h2>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Enregistrer</button>
</form>
{% endblock %}
{% block scripts %}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
$(document).ready(function() {
console.log('Document ready');
// Code pour filtrer les provinces en fonction du pays sélectionné
$("#id_adresse_country").change(function() {
console.log('Country changed');
var country_id = $(this).val();
if (country_id) {
axios.get("{% url 'get_provinces' %}", {params: {"country_id": country_id}})
.then(function(response) {
$("#id_adresse_province").html(response.data);
$("#id_adresse_city").html("<option value=''>---------</option>");
})
.catch(function(error) {
console.log(error);
});
debugger;
} else {
$("#id_adresse_province").html("<option value=''>---------</option>");
$("#id_adresse_city").html("<option value=''>---------</option>");
}
});
// Code pour filtrer les villes en fonction de la province sélectionnée
$("#id_adresse_province").change(function() {
console.log('Province changed');
var province_id = $(this).val();
if (province_id) {
axios.get("{% url 'get_cities' %}", {params: {"province_id": province_id}})
.then(function(response) {
$("#id_adresse_city").html(response.data);
})
.catch(function(error) {
console.log(error);
});
} else {
$("#id_adresse_city").html("<option value=''>---------</option>");
}
});
});
</script>
{% endblock %}
我的客户模型:
class Client(models.Model):
nom = models.CharField(max_length=100)
email = models.EmailField()
telephone = models.CharField(max_length=20, validators=[
RegexValidator(
regex=r'^\+?[0-9]{9,15}$',
message='Le numéro de téléphone doit être au format international (par exemple +33612345678)',
)])
adresse_country = models.ForeignKey(Country, on_delete=models.CASCADE)
adresse_province = models.ForeignKey(Province, on_delete=models.CASCADE)
adresse_city = models.ForeignKey(City, on_delete=models.CASCADE)
adresse_zip = models.CharField(max_length=200)
adresse_street = models.CharField(max_length=200)
status = models.ForeignKey(ClientStatus, on_delete=models.CASCADE, related_name='clients',default=1)
category = models.ForeignKey(ClientCategory, on_delete=models.CASCADE, related_name='clients', null=True)
tax_group = models.ForeignKey(Tax, on_delete=models.CASCADE, related_name='clients', null=True)
payment_term = models.ForeignKey(PaymentTerm, on_delete=models.CASCADE, related_name='clients', null=True)
我的表格:
class ClientForm(forms.ModelForm):
# afin de trier et selectionner un champ selon la 1ere lettre du mot
adresse_province = forms.ModelChoiceField(queryset=Province.objects.order_by('province'),
empty_label="Sélectionnez une province")
adresse_country = forms.ModelChoiceField(queryset=Country.objects.order_by('Country'),
empty_label="Sélectionnez un pays")
adresse_city = forms.ModelChoiceField(queryset=City.objects.order_by('city'), empty_label="Sélectionnez une ville")
# ne pas rendre obligatoire la saisie
email = forms.EmailField(required=False)
telephone = forms.CharField(required=False)
class Meta:
model = Client
fields = ['nom', 'email', 'telephone','adresse_country', 'adresse_province', 'adresse_street', 'adresse_city', 'adresse_zip',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.layout = Layout(
Row(
Column('nom', css_class='form-group col-md-6 mb-0'),
Column('email', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
Row(
Column('telephone', css_class='form-group col-md-6 mb-0'),
Column('adresse_street', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
Row(
Column('adresse_city', css_class='form-group col-md-4 mb-0'),
Column('adresse_zip', css_class='form-group col-md-4 mb-0'),
),
Row(
Column('adresse_province', css_class='form-group col-md-4 mb-0'),
Column('adresse_country', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Submit('submit', 'Enregistrer')
)
self.fields['adresse_province'].widget.attrs.update(
{'class': 'form-control select2', 'data-minimum-input-length': '2'})
self.fields['adresse_country'].widget.attrs.update(
{'class': 'form-control select2', 'data-minimum-input-length': '2'})
self.fields['adresse_city'].widget.attrs.update(
{'class': 'form-control select2', 'data-minimum-input-length': '2'})
我的问题是,当我选择一个国家时,我的省份字段没有任何变化。我查看控制台并将 console.logs 放入我的代码中,但 chrome 工具中没有显示日志...