Django中获取登录用户Customer并关联Infringer记录的问题排查
问题与代码修正
我自定义了User模型,其中包含customer字段,每个用户对应一个Customer。需要获取登录用户的Customer,以便添加Infringer记录时关联正确的Customer。我认为以下两处存在错误:
- views中表单实例化时传递的customer参数错误
- forms中过滤Customer的查询条件错误
原代码
views.py
@login_required(login_url='login') def createInfringer(request): customer=request.user.customer form = InfringerForm(customer=request.customer) if request.method == 'POST': form = InfringerForm(customer, request.POST) if form.is_valid(): form.save() return redirect('infringer-list') context ={'form': form} return render (request, 'base/infringement_form.html', context)
forms.py
class InfringerForm(ModelForm): def __init__(self, customer, *args, **kwargs): self.customer = customer super(InfringerForm,self).__init__(*args, **kwargs) self.fields['customer'].queryset = Customer.objects.filter(customer__user=self.customer) class Meta: model = Infringer fields = ['name', 'brand_name','status' , 'customer']
models.py
class Infringer (models.Model): name = models.CharField(max_length=200) brand_name = models.CharField(max_length=200, null=True) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) groups = models.ForeignKey(Group, on_delete=models.CASCADE,default=1) status = models.ForeignKey(Status, on_delete=models.SET_NULL,null=True) customer = models.ForeignKey(Customer, on_delete=models.SET_NULL,null=True) class Meta: ordering = ['-updated', '-created'] def __str__(self): return self.name class Customer (models.Model): name = models.CharField(max_length=200) email = models.EmailField(max_length=254, default='@cudo.ai') updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) phone_number = PhoneNumberField(blank=True) groups = models.ForeignKey(Group, on_delete=models.CASCADE,default=1) player = models.ManyToManyField(Player, related_name='player', blank=True) is_active = models.BooleanField(default=False) class Meta: ordering = ['name'] def __str__(self): return self.name class User(AbstractUser): email = models.EmailField(unique=True, null=True) avatar = models.ImageField(null=True, default="logo.svg") username = models.CharField(max_length=40, unique=False, default='') customer = models.ForeignKey(Customer, on_delete=models.SET_NULL,null=True)
修正方案
1. views.py 修正
- 表单实例化时,
request.customer不存在,应使用已获取的customer变量 - POST请求中,表单实例化参数顺序错误,且
redirect需放在表单验证通过的分支内,避免无效表单也跳转 - 可选优化:表单保存前手动设置customer,确保关联正确
修正后的代码:
@login_required(login_url='login') def createInfringer(request): customer = request.user.customer # 传递正确的customer参数 form = InfringerForm(customer=customer) if request.method == 'POST': # 按关键字参数传递,避免顺序问题 form = InfringerForm(customer=customer, data=request.POST) if form.is_valid(): infringer = form.save(commit=False) # 手动绑定当前用户的customer infringer.customer = customer infringer.save() # 验证通过后再跳转 return redirect('infringer-list') context = {'form': form} return render(request, 'base/infringement_form.html', context)
2. forms.py 修正
- 查询条件错误:User模型是
user.customer关联Customer,需直接匹配当前customer的ID,确保仅显示用户关联的Customer - 可选优化:将customer字段设为隐藏,避免用户手动修改
修正后的代码:
class InfringerForm(ModelForm): def __init__(self, customer, *args, **kwargs): self.customer = customer super(InfringerForm, self).__init__(*args, **kwargs) # 仅保留当前用户关联的Customer作为可选值 self.fields['customer'].queryset = Customer.objects.filter(id=self.customer.id) # 可选:隐藏customer字段,禁止用户修改 self.fields['customer'].widget = forms.HiddenInput() class Meta: model = Infringer fields = ['name', 'brand_name', 'status', 'customer']
内容的提问来源于stack exchange,提问作者Farid
相关产品推荐
相关产品推荐

