【问题标题】:Cannot assign "(<User: jack>, True)" "Profile.user" must be a "User" instance无法分配“(<User:jack>,True)”“Profile.user”必须是“User”实例
【发布时间】:2019-12-10 09:43:55
【问题描述】:

我使用与用户模型(配置文件)的一对一链接 当我尝试进行用户注册时出现此错误 无法分配“(,True)”:“Profile.user”必须是“用户”实例。 这是我项目中使用的 user_registration 感谢帮助

def user_registration(request):
    form = UserRegistrationForm()
      if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            structure= form.cleaned_data['structure'].id
            user = User.objects.get_or_create(username=username,  password=password)
            profile=Profile.objects.create(structure_id=structure,user=user)
            profile.save()
            messages.success(request,
            'Enregistrement avec succés {}'.format(user.username))
        return HttpResponseRedirect(reverse('compte:login'))   
    else:
        form = UserRegistrationForm()
        return render(request,'compte/register.html',{'form':form})

这是我的回溯:

[2019 年 8 月 1 日 22:01:13]“GET /compte/register/HTTP/1.1”200 2194 [01/Aug/2019 22:01:16]“GET /static/js/popper.min.js HTTP/1.1”404 1773 [01/Aug/2019 22:01:16]“GET /static/js/jquery-3.3.1.slim.min.js HTTP/1.1”404 1806 [01/Aug/2019 22:01:16]“GET /static/js/bootstrap.min.js HTTP/1.1”404 1782 [01/Aug/2019 22:01:16]“GET /compte/register/HTTP/1.1”200 2194 [01/Aug/2019 22:01:16]“GET /static/js/jquery-3.3.1.slim.min.js HTTP/1.1”404 1806 [01/Aug/2019 22:01:16]“GET /static/js/popper.min.js HTTP/1.1”404 1773 [01/Aug/2019 22:01:16]“GET /static/js/bootstrap.min.js HTTP/1.1”404 1782 内部服务器错误:/compte/register/ 回溯(最近一次通话最后): 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/exception.py”,第 34 行,在内部 响应 = get_response(请求) _get_response 中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/base.py”,第 115 行 response = self.process_exception_by_middleware(e, request) _get_response 中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/base.py”,第 113 行 响应 = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Users/mac/Desktop/investissement/Invest_App/compte/views.py”,第 38 行,在 user_registration profile=Profile.objects.create(structure_id=structure,user=user) 文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/manager.py”,第 82 行,在 manager_method 返回 getattr(self.get_queryset(), name)(*args, **kwargs) 创建文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/query.py”,第 420 行 obj = self.model(**kwargs) init 中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/base.py”,第 483 行 _setattr(self, field.name, rel_obj) set 中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py”,第 301 行 super().设置(实例,值) set 中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py”,第 211 行 self.field.remote_field.model._meta.object_name, ValueError:无法分配“(,True)”:“Profile.user”必须是“用户”实例。 [01/Aug/2019 22:01:25] "POST /compte/register/HTTP/1.1" 500 91942

【问题讨论】:

    标签: django


    【解决方案1】:

    get_or_create 返回项目的元组和指示它是否已创建的布尔值。您应该同时捕获两者:

    user, created = User.objects.get_or_create(username=username,  password=password)
    profile = Profile.objects.create(structure_id=structure,user=user)
    

    但是,您也不应该这样做。通过这样做,您可以确保密码在没有散列的情况下保存;无论如何,username 是一个唯一字段,因此如果用户名已经存在,则表单将无效。

    直接调用form.save:

    user = form.save()
    

    另请注意,您无需调用profile.save(),因为create 会保存项目本身。

    【讨论】:

    • 嗨丹尼尔,只是一个后续问题。这也可以通过保存用户来解决吗?例如user = user.save()?
    • @Paolo:不要设置user = user.save(),只设置user.save()
    • @WillemVanOnsem 太棒了!如果您应该设置用户,我很困惑。感谢您的澄清!
    【解决方案2】:

    .get_or_create(..) [Django-doc] 将返回一个 2 元组,其中包含对象生成的第一项,第二个是指定是否创建新对象的 boolean。因此,您可以在此处使用可迭代解包来访问第一个元素。

    def user_registration(request):
        form = UserRegistrationForm()
          if request.method == 'POST':
            form = UserRegistrationForm(request.POST)
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                structure = form.cleaned_data['structure'].id
                user, __ = User.objects.get_or_create(username=username,  password=password)
                profile = Profile.objects.create(structure_id=structure,user=user)
                profile.save()
                messages.success(request, 'Enregistrement avec succés {}'.format(user.username))
            return HttpResponseRedirect(reverse('compte:login'))   
        else:
            form = UserRegistrationForm()
            return render(request,'compte/register.html',{'form':form})

    话虽如此,上述方法不起作用,因为密码在数据库中保存为原始文本,而是经过哈希处理。您需要使用.set_password(..) [Django-doc] 设置密码。您可能希望将.update_or_create(..) [Django-doc] 用于您的Profile,以防止在该用户的配置文件已存在时出错:

    def user_registration(request):
        form = UserRegistrationForm()
          if request.method == 'POST':
            form = UserRegistrationForm(request.POST)
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                structure = form.cleaned_data['structure'].id
                user, __ = User.objects.get_or_create(username=username)
                user.set_password(password)
                user.save()
                Profile.objects.update_or_create(
                    user=user,
                    defaults={'structure_id': structure}
                )
                messages.success(request, 'Enregistrement avec succés {}'.format(user.username))
            return redirect('compte:login')
        else:
            form = UserRegistrationForm()
            return render(request,'compte/register.html',{'form':form})

    【讨论】:

    • 谢谢你我明白我会试试的,我告诉你结果谢谢
    • 我试了一下,我得到了这个错误:重复的键值违反了唯一约束“compte_profile_user_id_key”详细信息:键(user_id)=(13)已经存在。
    • @azizianoir:该错误意味着您已经为该用户创建了Profile。也许您也应该使用get_or_create 来代替Profile
    • 我通过添加 get_or_create 编辑视图,我得到了同样的错误:重复的键值违反了唯一约束“compte_profile_user_id_key”详细信息:键(user_id)=(14)已经存在。
    • @azizianoir:是update_or_create,而不是get_or_create
    猜你喜欢
    • 2015-01-05
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 2018-06-03
    相关资源
    最近更新 更多