You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django表单集字段过滤:仅显示当前用户创建的章节

Django InlineFormSet 字段过滤:仅显示当前用户的章节

要实现section字段仅展示当前用户创建的章节,你需要自定义表单类并在其中过滤字段的查询集,再将该表单关联到inlineformset。具体步骤如下:

1. 自定义Module表单类

创建继承自ModelForm的自定义表单,在初始化方法中接收当前用户,并过滤section字段的选项:

from django import forms
from django.forms.models import inlineformset_factory
from .models import Course, Module, Section

class ModuleForm(forms.ModelForm):
    class Meta:
        model = Module
        fields = ['title', 'section', 'description']

    def __init__(self, *args, **kwargs):
        # 取出并移除user参数,避免传递给父类构造方法
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        # 仅展示当前用户创建的章节
        if self.user:
            # 假设你的Section模型有user字段(关联创建章节的教师)
            self.fields['section'].queryset = Section.objects.filter(user=self.user)
            
            # 如果章节是关联到课程,且课程属于当前用户,可改用以下过滤逻辑:
            # self.fields['section'].queryset = Section.objects.filter(course__user=self.user)

2. 关联自定义表单到InlineFormSet

使用inlineformset_factory时,指定form参数为自定义表单:

ModuleFormSet = inlineformset_factory(
    Course,
    Module,
    form=ModuleForm,
    extra=2,
    can_delete=True
)

3. 在视图中传递当前用户给FormSet

初始化formset时,通过form_kwargs参数将当前登录用户传递给每个表单实例:

函数视图示例

from django.shortcuts import render, redirect
from django.http import HttpResponseForbidden
from .forms import ModuleFormSet
from .models import Course

def edit_course_modules(request, course_id):
    course = Course.objects.get(id=course_id)
    
    # 权限校验:确保当前用户是课程的创建者
    if course.user != request.user:
        return HttpResponseForbidden()
    
    if request.method == 'POST':
        formset = ModuleFormSet(
            request.POST,
            instance=course,
            form_kwargs={'user': request.user}
        )
        if formset.is_valid():
            formset.save()
            return redirect('course_detail', course_id=course.id)
    else:
        formset = ModuleFormSet(
            instance=course,
            form_kwargs={'user': request.user}
        )
    
    return render(request, 'edit_modules.html', {'formset': formset, 'course': course})

类视图(UpdateView)示例

如果你使用基于类的视图,可以重写get_form_kwargs方法传递用户:

from django.views.generic.edit import UpdateView
from .models import Course
from .forms import ModuleFormSet

class CourseModuleUpdateView(UpdateView):
    model = Course
    fields = []  # 不需要编辑Course本身的字段,仅处理formset
    template_name = 'edit_modules.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 初始化formset并传递用户
        if self.request.POST:
            context['formset'] = ModuleFormSet(
                self.request.POST,
                instance=self.object,
                form_kwargs={'user': self.request.user}
            )
        else:
            context['formset'] = ModuleFormSet(
                instance=self.object,
                form_kwargs={'user': self.request.user}
            )
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']
        if formset.is_valid():
            self.object = form.save()
            formset.save()
            return super().form_valid(form)
        else:
            return self.render_to_response(self.get_context_data(form=form))

关键说明

  • 过滤逻辑需根据你的实际模型结构调整:如果Section模型通过外键关联到Course,而Course属于当前用户,就用course__user=self.user作为过滤条件;如果Section直接关联到用户,则用user=self.user。
  • 务必添加权限校验,确保用户只能编辑自己创建的课程模块,避免越权操作。

内容的提问来源于stack exchange,提问作者Maxim Bekurin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:48:13