我希望你觉得这个提议很有趣:
Views.py:
def view1(request):
CourseComponentFormSet = formset_factory(CourseComponentForm, extra=Component.objects.count())
content = {'form': CourseComponentFormSet}
return render(request, 'stack/edit.html', content)
def view2(request, mycourse):
if request.method == 'POST':
data = {}
for p in request.POST:
if p.startswith('form'):
data[p] = request.POST[p]
j = 0
while j < int(data['form-MAX_NUM_FORMS']):
if data['form-' + str(j) + '-quantity'] == '':
data['form-' + str(j) + '-quantity'] = 0
data['form-' + str(j) + '-course'] = mycourse
else:
data['form-' + str(j) + '-course'] = mycourse
j += 1
CourseComponentFormSet = formset_factory(CourseComponentForm)
formset = CourseComponentFormSet(data)
if formset.is_valid():
j = 0
mylist = []
while j < int(data['form-MAX_NUM_FORMS']):
if data['form-' + str(j) + '-quantity'] == 0:
pass
else:
Courses = get_object_or_404(Course, name=mycourse)
Components = get_object_or_404(Component, id=int(data['form-' + str(j) + '-component']))
Courses.components.add(Components,
through_defaults={'quantity': data['form-' + str(j) + '-quantity']})
j += 1
return HttpResponseRedirect(reverse('stack:view1'))
else:
errors = formset.errors
ini = []
i = 0
nb = Component.objects.count()
while i < nb:
ini.append({'course': mycourse})
i += 1
CourseComponentFormSet = formset_factory(CourseComponentForm, max_num=nb)
formset = CourseComponentFormSet(initial=ini)
content = {'form': formset, 'course': mycourse, 'errors': errors}
return render(request, 'stack/edit.html', content)
else:
if Course.objects.filter(name__exact=mycourse):
pass
else:
Course.objects.create(**{'name': mycourse})
ini = []
i = 0
nb = Component.objects.count()
while i < nb:
ini.append({'course': mycourse})
i += 1
CourseComponentFormSet = formset_factory(CourseComponentForm, max_num=nb)
formset = CourseComponentFormSet(initial=ini)
content = {'form': formset, 'course': mycourse}
return render(request, 'stack/edit.html', content)
模型.py
class Component(models.Model):
name = models.CharField(max_length=200, null=False, unique=True)
def __str__(self):
return self.name
class Course(models.Model):
name = models.CharField(max_length=200, null=False, unique=True)
components = models.ManyToManyField('Component', through='CourseComponent')
def __str__(self):
return self.name
class CourseComponent(models.Model):
component = models.ForeignKey(Component, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0, null=False)
def __init__(self, *args, **kwargs):
super(CourseComponent, self).__init__(*args, **kwargs)
forms.py
class CourseComponentForm(Form):
course = CharField(label='Course')
component = ChoiceField(label='Component')
quantity = IntegerField(label='Quantity')
def __init__(self, *args, **kwargs, ):
super(CourseComponentForm, self).__init__(*args, **kwargs)
self.fields['component'].choices = tuple(Component.objects.all().values_list(flat=False))
self.fields['quantity'].widget.attrs['style'] = "margin:15px 56% 15px 0%;"
self.fields['course'].widget.attrs['readonly'] = "True"
self.fields['course'].widget.attrs['disabled'] = "disabled"
edit.html
<body>
<label>Course:</label><input id="myinput" type="text"><button onclick="myfunction()">send</button><br>'
<form action='' id='myform' method="POST">
{% csrf_token %}
{{ form }}
<button class="btn btn-primary" name="submit" onclick="submit()">submit</button>
</form>
{{errors}}
</body>
<script>
{% if mycourse %}
{% endif %}
function submit() {
document.getElementById('myform').action="/stack/view2/"+mycourse;
document.getElementById("myform").submit();
}
function myfunction() {
var course = document.getElementById("myinput").value;
chemin ="\/stack\/view2\/"+course;
window.location.replace(chemin);
}
</script>
</html>