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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:32:52