Django CreateView类中能否获取当前登录用户ID并保存关联表?
问题分析与解决方案
首先明确回答:在CreateView子类里完全可以获取当前登录用户的ID,你保存失败的问题不是出在用户ID的获取上,而是表单处理、中间表定义以及类视图用法这几个地方有错误,下面逐一拆解并修正:
1. 表单处理的致命错误
你在creation函数里的表单逻辑完全错了:
- 首先
form.is_valid少了括号,应该是form.is_valid(),这会导致判断永远为True(因为你取的是函数对象本身,不是执行结果); - 更严重的是,当你判断表单有效后,又重新实例化了一个空的
myForm(),这直接把用户POST过来的表单数据丢了!所以form.id根本没有值,自然无法保存到中间表。
2. 用户ID获取的小问题与登录验证
你一会儿用self.request.user.id,一会儿用request.user.id,虽然两种方式在函数传了request的情况下都能工作,但在类视图里更推荐统一用self.request.user。另外一定要确保用户已登录,否则request.user是匿名用户,id会是None,导致保存失败。可以给类视图加上LoginRequiredMixin来强制登录。
3. 中间表的主键问题
你的Item_id_user模型手动定义了id = models.IntegerField(primary_key=True),但保存时你没有给这个字段赋值,数据库会因为主键缺失而拒绝保存。解决方法很简单:删掉这个手动定义的id字段,Django会自动为你创建一个自增的整数主键,完全不需要手动干预。
4. 符合Django规范的正确写法
CreateView本身提供了form_valid方法来处理表单验证后的逻辑,没必要自己写一个creation函数,这样更符合Django类视图的设计思路。
修正后的代码
models.py 修改
from django.contrib.auth.models import User from django.db import models class Item(models.Model): id_user = models.ManyToManyField( User, related_name='user_item', verbose_name='id utente', through='Item_id_user' ) # 无需手动声明object = models.Manager(),Django默认会添加 class Item_id_user(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) item = models.ForeignKey(Item, on_delete=models.CASCADE) # 移除手动定义的id字段,让Django自动生成主键
views.py 修改
from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView from .models import Item, Item_id_user from .forms import MyForm class CreationClass(LoginRequiredMixin, CreateView): model = Item form_class = MyForm success_url = '/mypage/' # 也可以用reverse_lazy指定URL名称,更灵活 def form_valid(self, form): # 先保存Item实例 self.object = form.save() # 创建中间表记录,关联当前登录用户和刚创建的Item Item_id_user.objects.create( user=self.request.user, item=self.object ) return super().form_valid(form)
额外说明
- 如果你的
MyForm是基于Item模型的ModelForm,form.save()会自动创建Item实例,你只需要在form_valid里完成用户关联即可; LoginRequiredMixin能确保只有登录用户才能访问创建页面,避免匿名用户导致request.user.id为None的问题;- 如果你坚持要自定义
creation函数(不推荐),也要先处理表单并保存Item实例,再关联用户,绝对不能重新实例化空表单。
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

