我使用的是Django 2.2,这是我的简化模型:
class Course(CustomModelClass):
name = models.CharField(max_length=200, null=False, unique=True)
components = models.ManyToManyField('Component', through='CourseComponent')
class Component(CustomModelClass):
name = models.CharField(max_length=200, null=False, unique=True)
class CourseComponent(CustomModelClass):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
component = models.ForeignKey(Component, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0, null=False)
我的人际关系很好,没有问题。现在到我创建一个ModelForm来管理它的时候。
现在是我的表格:
class CourseForm(ModelForm):
class Meta:
fields = ['name', 'group', 'components']
model = Course
如果我的数量具有null = True参数,同样可以很好地工作,但是当我将其设置为False时,它显然不再起作用。
我想做的是以一种形式选择零件并为每个零件设置数量。我并不在乎它看起来像是带有组件名称和数字字段的复选框,还是选择组件和数字字段的许多选择列表,这并不是重要的部分。
更清楚地讲,我想用相同的形式创建一个对象及其与其他字段的许多关系。
我现在的问题是,我当然无法访问表格中的数量。
有什么主意吗?
答案 0 :(得分:0)
我希望您对这个建议感兴趣:
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)
model.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>
答案 1 :(得分:0)
from django import forms
from .models import Course, Component
class CourseForm(ModelForm):
class Meta:
fields = ['name']
model = Course
class ComponentForm(forms.Form):
component = forms.ModelChoiceField(queryset=Component.objects.all())
quantity = forms.IntegerField(initial=0, required=False, min_value=0)
ComponentFormSet = forms.formset_factory(ComponentForm, extra=3)
def handler(request):
if request.method == "POST":
form = CourseForm(request.POST)
formset = ComponentFormSet(request.POST)
if form.is_valid() and formset.is_valid():
# do your business
form = CourseForm() #it could set initial data here for form,etc
formset = ComponentFormSet()
return render(request, 'your_template.html', {'form':form, 'formset':formset})
{% extends 'admin/base_site.html'%}
{% load i18n %}
{% block content%}
<div class="col-md-10">
<form action={% url "course" %} method='post' role='form' class="form-inline">
{% csrf_token %}
{{ form }}<br>
{{ formset.management_form}}
{% for fm in formset %}
{{ fm }}<br>
{% endfor%}
<input type='submit' class='btn btn-primary' value="submit"/>
</form>
</div>
{% endblock%}