У меня есть трехстраничный список форм, выходящий из одной модели, и я хочу отобразить Колледжи в зависимости от процентного выбора на втором шаге, но он отображает список всех колледжей из базы данных на третьем шаге.
как отобразить список колледжей на основе процента в Django -FormWizardView
Вот мои models.py
class Percentage(models.Model):
number = models.CharField(max_length=100)
def __str__(self):
return self.number
class College(models.Model):
percentage = models.ForeignKey(Percentage, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Student(models.Model):
user=models.ForeignKey(User,on_delete=models.CASCADE)
firstname = models.CharField(max_length=100,validators=[alphanumeric])
lastname = models.CharField(max_length=100,validators=[alphanumeric])
image=models.ImageField(upload_to='files/%Y/%m/%d', blank=True)
percentage = models.ForeignKey(Percentage, on_delete=models.SET_NULL, null=True)
college = models.ForeignKey(College, on_delete=models.SET_NULL, null=True)
description=models.TextField(blank=True)
def __str__(self):
return self.firstname
forms.py
class FirstForm(forms.ModelForm):
id = forms.IntegerField(widget=forms.HiddenInput, required=False)
firstname = models.CharField(max_length=100,validators=[alphanumeric])
class Meta:
model = Student
fields = ('firstname',)
class SecondForm(forms.ModelForm):
lastname = models.CharField(max_length=100,validators=[alphanumeric])
image = forms.ImageField(required=False)
class Meta:
model=Student
fields=('lastname','image','percentage')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['percentage'].widget.attrs={ 'id': 'percentage', 'label':'percentage',
'name': 'percentage'}
def save(self, commit=True):
user = super(SecondForm, self).save(commit=False)
user.percentage = self.cleaned_data['percentage']
if commit:
user.save()
return user
class ThirdForm(forms.ModelForm):
description = forms.CharField(widget=forms.Textarea)
class Meta:
model = Student
fields = ('college','description',)
def __init__(self, *args, **kwargs):
super(ThirdForm, self).__init__(*args, **kwargs)
self.fields['description'].widget.attrs={ 'id': 'id_description',
'class': 'myDescriptionClass',
'name': 'myDescriptionName',
'placeholder': 'myDescriptionholder'}
self.fields['college'].widget.attrs = {'id': 'college', 'label': 'college'}
if 'percentage' in self.data:
try:
percentage = int(self.data.get('percentage'))
self.fields['college'].queryset = College.objects.filter(percentage=percentage).order_by('name')
except (ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['college'].queryset = College.objects.none()
self.fields['college'].queryset = self.instance.percentage.college_set.order_by('name')
views.py
class StWizard(SessionWizardView):
template_name = "/stwizard_form.html"
file_storage = DefaultStorage()
#if you are uploading files you need to set FileSystemStorage
def done(self, form_list, **kwargs):
for form in form_list:
print (form.initial)
if not self.request.user.is_authenticated:
raise Http404
instance = Student()
# moved for out of if
for form in form_list:
for field, value in form.cleaned_data.items():
setattr(instance, field, value)
instance.user = self.request.user
instance.save()
return render_to_response('/stwizard_done.html', {
'form_data': [form.cleaned_data for form in form_list], })
def edit_stwizard(request, id):
#get the object
item = get_object_or_404(Student, pk=id)
#make sure the item belongs to the user
if item.user != request.user:
raise HttpResponseForbidden()
else:
#get the initial data to include in the form
initial = {'0': {'id': item.id,
'firstname': item.firstname,
},
'1': {'lastname':item.lastname,
'image': item.image,
'percentage': item.percentage,
},
'2': {'college': item.college,
'description': item.description,
},
}
print (initial)
form = StWizard.as_view([FirstForm, SecondForm, ThirdForm], initial_dict=initial)
return form(context=RequestContext(request),request=request)
def load_colleges(request):
percentage = request.GET.get('percentage')
colleges = College.objects.filter(percentage=percentage).order_by('name')
return render(request, '/college_dropdown_list_options.html', {'colleges': colleges})
wizard_form. html
{% block content %}
<p> {{ wizard.steps. }} {{ wizard.steps. }}</p>
<form method="post" enctype="multipart/form-data" id="personFor" data-colleges-url="{% url 'ajax_load_colleges' %}"
>
{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form|crispy }}
{% endif %}
</table><br>
{% if wizard.steps.prev %}
<button formnovalidate="formnovalidate" name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button formnovalidate="formnovalidate" name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" >{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="submit" />
</form>
{% endblock %}
urls.py
path('student/', StWizard.as_view([FirstForm, SecondForm, ThirdForm]), name='stwizards'),
re_path(r'^stedit/(?P<id>\d+)/$', StWizard.edit_stwizard, name='edit_stwizard'),
js
$("#percentage").change(function (){
var url = $("#personFor").attr("data-colleges-url");
var percentageId = $(this).val();
if(document.getElementsByTagName("form")[0].id == 'personFor' && percentageId){
$.ajax({
"url": url,
"data": {
'percentage': percentageId
},
success: function (data) {
console.log(data);
$("#college").html(data);
}
});
}
});