首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义格式集:-分配外键值并只输入一次[登录用户]

自定义格式集:-分配外键值并只输入一次[登录用户]
EN

Stack Overflow用户
提问于 2019-05-13 15:25:47
回答 2查看 54关注 0票数 0

我有一个模型集来填充时间表模型。

模型

代码语言:javascript
复制
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)

视图

代码语言:javascript
复制
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')

表单

代码语言:javascript
复制
class Timetableform(ModelForm):
    class Meta:
        model = Timetable
        fields = ( 'start', 'end', 'period')

TimetableFormSet = modelformset_factory(Timetable, fields=('start', 'end', 'period'),extra=8,)

模板

代码语言:javascript
复制
<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就像一般的表单一样。

要求

  1. webapp有一个登录功能。当用户( classteacher )登录时,他们可以添加时间表。我想要的是时间表中的分类器字段(模型形式)应该被自动设置为用户,这是类传送器。(克拉斯泰克)在创建时间表后应该保存在数据库中。Classteacher模型根据各自需要的字段进行更新。

我试着将classteacher传递到formset,但它是根据我的需要执行的。

我知道如何在正常的表单中这样做,但我还没有在一个格式集中这样做。

  1. Timetable中的day字段应该只选择一次,因此将有8个表单来提供start endperiod,但是应该只有一个表单来提供day。我成功地为start endperiod处理了8份表单,但对day一无所知。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-15 08:52:09

有更好的方法来做到这一点:

  • 如果使用inlineformset_factory,则可以在初始化窗体集时直接传递表单集所属的教师实例。参见示例这里
  • 或者可以循环遍历表单,以便在保存实例之前修改它们: 实例= formset.save(commit=False)实例中的实例: instance.classteacher =.instance.save()

如果希望用户提交对所有实例通用的额外字段,则可以向视图中添加另一种表单:

代码语言:javascript
复制
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(...)

模板渲染

代码语言:javascript
复制
<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>
票数 2
EN

Stack Overflow用户

发布于 2019-05-13 18:47:37

在CreateView中,您可以重写get_initial方法:

代码语言:javascript
复制
def get_initial(self):
    self.initial = CreateView.get_initial(self)
    self.initial["classteacher"] = self.request.user
return self.initial.copy()

然后,您需要将此字段添加到窗体中。

代码语言:javascript
复制
class Timetableform(ModelForm):
    class Meta:
        model = Timetable
        fields = ( 'start', 'end', 'period', “classteacher”)

如果您不想在表单中显示此字段,但仍将classteacher添加为当前用户,则可以在此字段中使用Hiddeninput小部件:

代码语言:javascript
复制
class Timetableform(ModelForm):
    class Meta:
        model = Timetable
        fields = ( 'start', 'end', 'period', “classteacher”)
           widgets = {"classteacher": HiddenInput}

在表单集中,您也可以使用隐藏输入小部件,或者在构造函数中使用form=Timetableform参数。同理

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56115453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档