如何使用基于类的视图(CBV)按created_by字段过滤外键数据
嘿,我来帮你搞定用基于类的视图(CBV)按created_by字段过滤外键数据的需求!根据你给出的模型和视图代码,我整理了两种可行的方案,你可以根据自己的场景选择:
方法一:直接在视图中重写
get_form方法 这种方法简单直接,适合快速修改现有视图:
from django.contrib.auth.mixins import LoginRequiredMixin from django.views import generic from .models import InvoiceLine, Item class InvoiceCreateView(LoginRequiredMixin, generic.CreateView): template_name = "books/invoice_create_or_update.html" model = InvoiceLine # 补全你没写完的model属性 fields = ['invoice', 'name', 'tax_rate'] # 定义要显示的表单字段 def get_form(self, form_class=None): # 先获取父类生成的表单 form = super().get_form(form_class) # 过滤Item字段,只显示当前登录用户创建的条目 form.fields['name'].queryset = Item.objects.filter(created_by=self.request.user) # 如果你的TaxRate模型也有created_by字段,同理过滤: # form.fields['tax_rate'].queryset = TaxRate.objects.filter(created_by=self.request.user) return form
方法二:自定义表单类(更灵活)
如果后续表单逻辑会更复杂,推荐用这种方式,把表单逻辑和视图分离:
首先创建表单文件forms.py:
from django import forms from .models import InvoiceLine, Item, TaxRate class InvoiceLineForm(forms.ModelForm): class Meta: model = InvoiceLine fields = ['invoice', 'name', 'tax_rate'] def __init__(self, *args, **kwargs): # 从参数中取出当前用户,再传给父类构造方法 user = kwargs.pop('user') super().__init__(*args, **kwargs) # 过滤Item选项 self.fields['name'].queryset = Item.objects.filter(created_by=user) # 同理处理TaxRate(如果有created_by字段的话) # self.fields['tax_rate'].queryset = TaxRate.objects.filter(created_by=user)
然后修改视图:
from django.contrib.auth.mixins import LoginRequiredMixin from django.views import generic from .forms import InvoiceLineForm class InvoiceCreateView(LoginRequiredMixin, generic.CreateView): template_name = "books/invoice_create_or_update.html" form_class = InvoiceLineForm def get_form_kwargs(self): # 把当前用户传递给表单 kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user return kwargs
关键注意事项
- 必须加上
LoginRequiredMixin:确保只有登录用户才能访问这个视图,避免request.user是匿名用户导致过滤失效。 - 如果你不需要过滤
tax_rate字段(比如TaxRate模型没有created_by),直接删掉对应的过滤代码即可。 - 记得补全视图中未写完的
model或form_class属性,否则视图无法正常工作。
内容的提问来源于stack exchange,提问作者Mike Pinkman
相关产品推荐
相关产品推荐

