#django #django-views #django-forms
Вопрос:
У меня проблема с выбором, который фильтрует другой. Я правильно выполнил всю фильтрацию с точки зрения интерфейса, но в серверной части я не могу сохранить данные. Это ошибка:
выберите правильный выбор. Этот выбор не является одним из доступных вариантов.
Я следую статье (https://simpleisbetterthancomplex.com/tutorial/2018/01/29/how-to-implement-dependent-or-chained-dropdown-list-with-django.html ), но не работает. Я думаю, что проблема заключается в том, что форма не находит ‘group_single’, который я передаю через post в своих представлениях.
models.py
class Gruppi(models.Model):
nome_gruppo = models.CharField(max_length=100)
class Esercizi(models.Model):
nome_esercizio = models.CharField(max_length=100)
gruppo = models.ForeignKey(
Gruppi,
on_delete = models.CASCADE,
related_name = 'gruppo'
)
class Schede(models.Model):
nome_scheda = models.CharField(max_length=100)
data_inizio = models.DateField()
data_fine = models.DateField()
utente = models.ForeignKey(
User,
on_delete = models.CASCADE,
related_name = 'utente'
)
class DatiGruppi(models.Model):
giorni_settimana_scelta = [
("LUNEDI","Lunedì"),
("MARTEDI","Martedì"),
("MERCOLEDI","Mercoledì"),
("GIOVEDI","Giovedì"),
("VENERDI","Venerdì"),
("SABATO","Sabato"),
("DOMENICA","Domenica")
]
giorni_settimana = MultiSelectField(
choices = giorni_settimana_scelta,
default = '-'
)
dati_gruppo = models.ForeignKey(
Gruppi,
on_delete = models.CASCADE,
related_name = 'dati_gruppo'
)
gruppi_scheda = models.ForeignKey(
Schede,
on_delete = models.CASCADE,
related_name = 'gruppi_scheda'
)
class DatiEsercizi(models.Model):
serie = models.IntegerField()
ripetizione = models.IntegerField()
peso = models.DecimalField(
max_digits = 4,
decimal_places = 1,
blank = True,
null = True
)
dati_esercizio = models.ForeignKey(
Esercizi,
on_delete = models.CASCADE,
related_name = 'dati_esercizio'
)
gruppo_single = models.ForeignKey(
DatiGruppi,
on_delete = models.CASCADE,
related_name = 'gruppo_single'
)
forms.py
class EserciziForm(forms.ModelForm):
class Meta:
model = models.DatiEsercizi
exclude = ['gruppo_single']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['dati_esercizio'].queryset = models.Esercizi.objects.none()
if 'gruppo_single' in self.data:
try:
gruppo_id = int(self.data.get('gruppo_single'))
print("<----------ciao sono qui ------>", gruppo_id)
self.fields['dati_esercizio'].queryset = models.Esercizi.objects.filter(gruppo_id = gruppo_id)
except (ValueError, TypeError):
pass
else:
print("<----------errore ------>")
class GruppiForm(forms.ModelForm):
class Meta:
model = models.DatiGruppi
exclude = ['gruppi_scheda']
views.py
def creazione(request, nome):
scheda = get_object_or_404(Schede, nome_scheda = nome)
eserciziFormSet = formset_factory(EserciziForm, extra = 1)
if request.method == "POST":
#form con dati post
gruppo_form = GruppiForm(request.POST, prefix = 'gruppo')
esercizi_formset = eserciziFormSet(request.POST, prefix='esercizi')
#gruppi
if gruppo_form.is_valid() and esercizi_formset.is_valid():
gruppo = gruppo_form.save(commit = False)
gruppo.gruppi_scheda = scheda
gruppoName = gruppo_form.cleaned_data['dati_gruppo']
gruppo.save()
#esercizi
for esercizi in esercizi_formset:
esercizi_instance = esercizi.save(commit = False)
esercizi_instance.gruppo_single = get_object_or_404(DatiGruppi, gruppi_scheda = scheda.id, dati_gruppo = gruppoName)
esercizi_instance.save()
return HttpResponseRedirect(request.path_info)
else:
#filtro esclusione gruppi già aggiunti
group_to_add = Gruppi.objects.exclude(dati_gruppo__gruppi_scheda = scheda)
GruppiForm.base_fields['dati_gruppo'] = forms.ModelChoiceField(queryset = group_to_add)
gruppo_form = GruppiForm(prefix = 'gruppo')
esercizi_formset = eserciziFormSet(prefix='esercizi')
gruppi_db = Gruppi.objects.all()
context = {'scheda' : scheda, 'gruppo_form' : gruppo_form, 'esercizi_formset': esercizi_formset, 'gruppi_db': gruppi_db}
return render(request, 'crea/passo2.html', context)
#filtro gruppi-esercizi
def caricamento_esercizi(request):
gruppo_id = request.GET.get('gruppo')
esercizi_add = Esercizi.objects.filter(gruppo_id = gruppo_id)
context = {'esercizi_add': esercizi_add}
return render(request, 'filtro_esercizi.html', context)
ajax call
<script>
$("#id_gruppo-dati_gruppo").change(function(){ //al cambiamento della select gruppi
var url = $("#creazione_scheda").attr("data-esercizi-url"); //prendo l'url presente in data-esercizi-url
var gruppoId = $(this).val(); //salvo il valore della select gruppi
$.ajax({
url: url,
data:{
'gruppo': gruppoId
},
success: function(data){
$(".esercizi select").html(data);
}
});
});
</script>