Django中CreateView过滤关联Album数据失效问题求助
问题解决:限制CreateView中外键字段仅显示当前用户的关联数据
问题原因
你在CreatePrimary里重写的get_queryset是用来控制列表视图的查询结果,管不到表单里外键字段的选项列表。要过滤year_of_graduation的Album选项,得直接修改表单字段的查询集。
解决方案
方法1:重写CreateView的get_form方法
直接在视图里动态修改表单字段的可选范围,只保留当前用户的Album:
class CreatePrimary(CreateView): model = Primary fields = ['profilePicture', 'first_name', 'last_name', 'year_of_graduation'] template_name = 'create_primary.html' success_url = '/Home/' # 这里要写实际URL路径,用命名URL的话可以用reverse_lazy def get_form(self, form_class=None): form = super().get_form(form_class) # 过滤year_of_graduation的选项,只显示当前用户的Album form.fields['year_of_graduation'].queryset = Album.objects.filter(user=self.request.user) return form def form_valid(self, form): form.instance.user = self.request.user return super(CreatePrimary, self).form_valid(form)
方法2:自定义表单类
如果后续有更复杂的表单逻辑,单独定义表单类更灵活:
from django import forms from .models import Primary, Album class PrimaryCreateForm(forms.ModelForm): class Meta: model = Primary fields = ['profilePicture', 'first_name', 'last_name', 'year_of_graduation'] def __init__(self, *args, **kwargs): user = kwargs.pop('user') # 从参数里拿当前用户 super().__init__(*args, **kwargs) self.fields['year_of_graduation'].queryset = Album.objects.filter(user=user) # 对应的视图修改 class CreatePrimary(CreateView): model = Primary form_class = PrimaryCreateForm template_name = 'create_primary.html' success_url = '/Home/' def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user # 把当前用户传给表单 return kwargs def form_valid(self, form): form.instance.user = self.request.user return super(CreatePrimary, self).form_valid(form)
额外修正:代码里的拼写错误
你的模型代码有几个拼写问题,会直接导致运行报错,必须改:
Class→class(Python类定义用小写class)charfield→CharField(Django字段类首字母大写)FilesField→FileField(单个文件用FileField,图片的话推荐用ImageField,需要装Pillow)Foreignkey→ForeignKey
修正后的模型代码:
from django.contrib.auth.models import User from django.db import models class Album(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=20) class Primary(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) # 你之前的Primary没定义user字段,但form_valid里设置了,必须加上 profilePicture = models.FileField(upload_to='image') first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) year_of_graduation = models.ForeignKey(Album, on_delete=models.CASCADE)
内容的提问来源于stack exchange,提问作者Adamu Abdulkarim Dee
相关产品推荐
相关产品推荐

