我有一个模型集来填充时间表模型。
模型
class Timetable(models.Model):
day = models.ForeignKey('Day',on_delete=models.CASCADE)
start = models.IntegerField()
end = models.IntegerField()
period = models.CharField(max_length=12)
classteacher = models.ForeignKey('Class_teacher',on_delete=models.SET_NULL)
class Class_teacher(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
empid = models.CharField(max_length=10)
email = models.CharField(max_length=30)视图
class Timetableadding(CreateView):
model = Timetable
success_url = '/dashboard'
form_class = Timetableform
template_name = 'newtest.html'
def get_context_data(self, **kwargs):
context = super(Timetableadding, self).get_context_data(**kwargs)
context['formset'] = TimetableFormSet(queryset=Timetable.objects.none())
return context
def post(self, request, *args, **kwargs):
formset = TimetableFormSet(request.POST)
if formset.is_valid():
return self.form_valid(formset)
def form_valid(self, formset):
formset.classteacher = get_object_or_404(Class_teacher, email=self.request.user.email)
formset.save()
# return super().form_valid(formset)
return HttpResponseRedirect('/dashboard')表单
class Timetableform(ModelForm):
class Meta:
model = Timetable
fields = ( 'start', 'end', 'period')
TimetableFormSet = modelformset_factory(Timetable, fields=('start', 'end', 'period'),extra=8,)模板
<form class="form-material m-t-40 floating-labels" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form }}<br><br>
{% endfor %}
<div class="form-group row">
<button type="submit" class="btn waves-effect waves-light btn-rounded btn-success">
Submit
</button>
</div>
</form>当使用createview视图填充Timetableform时,Timetable模型中的字段Timetable就像一般的表单一样。
要求
我试着将classteacher传递到formset,但它是根据我的需要执行的。
我知道如何在正常的表单中这样做,但我还没有在一个格式集中这样做。
Timetable中的day字段应该只选择一次,因此将有8个表单来提供start end和period,但是应该只有一个表单来提供day。我成功地为start end和period处理了8份表单,但对day一无所知。发布于 2019-05-15 08:52:09
有更好的方法来做到这一点:
inlineformset_factory,则可以在初始化窗体集时直接传递表单集所属的教师实例。参见示例这里。如果希望用户提交对所有实例通用的额外字段,则可以向视图中添加另一种表单:
class DayForm(forms.Form):
day = ModelChoiceField(queryset=Day.objects.all())
def get_context_data(self, **kwargs):
...
context['day_form'] = DayForm()
return context
def post(self, *args, **kwargs):
...
day_form = DayForm(data=request.POST)
if formset.is_valid() and day_form.is_valid():
return self.form_valid(formset, day_form)
def form_valid(self, formset, day_form):
day = day_form.cleaned_data['day']
instances = formset.save(commit=False)
for instance in instances:
instance.day = day
instance.teacher = ...
instance.save()
return HttpResponseRedirect(...)模板渲染
<form class="form-material m-t-40 floating-labels" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ day_form }} <br>
{{ formset.management_form }}
{% for form in formset %}
{{ form }}<br><br>
{% endfor %}
<div class="form-group row">
<button type="submit" class="btn waves-effect waves-light btn-rounded btn-success">
Submit
</button>
</div>
</form>发布于 2019-05-13 18:47:37
在CreateView中,您可以重写get_initial方法:
def get_initial(self):
self.initial = CreateView.get_initial(self)
self.initial["classteacher"] = self.request.user
return self.initial.copy()然后,您需要将此字段添加到窗体中。
class Timetableform(ModelForm):
class Meta:
model = Timetable
fields = ( 'start', 'end', 'period', “classteacher”)如果您不想在表单中显示此字段,但仍将classteacher添加为当前用户,则可以在此字段中使用Hiddeninput小部件:
class Timetableform(ModelForm):
class Meta:
model = Timetable
fields = ( 'start', 'end', 'period', “classteacher”)
widgets = {"classteacher": HiddenInput}在表单集中,您也可以使用隐藏输入小部件,或者在构造函数中使用form=Timetableform参数。同理
https://stackoverflow.com/questions/56115453
复制相似问题