【问题标题】:Django - get user id after saving the userDjango - 保存用户后获取用户ID
【发布时间】:2019-12-11 06:14:41
【问题描述】:

我正在使用 Python(3.7) 和 Django(2.2) 开发一个项目,其中我已经为多种类型的用户实现了模型,并通过使用 MultiModleForm 在前端显示为单个表单来组合模型,之后当我尝试在视图中创建用户并调用 user 模型的保存方法并尝试获取其 id 但它给出了错误。

这是我迄今为止尝试过的:

来自models.py

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    title = models.CharField(max_length=255, blank=False)
    user_type = models.CharField(max_length=255, choices=USER_TYPE, blank=False)
    gender = models.CharField(max_length=255, choices=CHOICES, blank=False)
    contenst = models.CharField(max_length=255, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['password']

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)

class Parent(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    contact_email = models.EmailField(blank=False)
    customer_id = models.BigIntegerField(blank=False)
    contact_no = PhoneNumberField(blank=True, help_text='Phone number must be entered in the'
                                                        'format: \'+999999999\'. Up to 15 digits allowed.')
    collection_use_personal_data = models.BooleanField(blank=False)

来自forms.py

class ParentForm(forms.ModelForm):

    class Meta:
        model = Parent
        fields = ('contact_email', 'contact_no', 'collection_use_personal_data')


class UserParentForm(MultiModelForm):
    form_classes = {
        'user': UserForm,
        'profile': ParentForm
    }

来自views.py

def post(self, request, *args, **kwargs):
    print(request.POST)
    user_type = request.POST.copy()['user-user_type']
    form = None
    if user_type == 'PB':
        form = UserBelow18Form(request.POST)
    elif user_type == 'PA':
        form = UserAbove18Form(request.POST)
    elif user_type == 'Parent':
        form = UserParentForm(request.POST)
        print('user-parent form selected')
    elif user_type == 'GC':
        form = UserGCForm(request.POST)

    if form.is_valid():
        user = form['user']
        profile = form['profile']
        if user_type == 'Parent' or user_type == 'GC':
            c_id = generate_cid()
            profile.customer_id = c_id
            print('id generated for parent or GC: {}'.format(c_id))

            try:
                user.save()
                profile.user = User.objects.get(id=user.id)
                # print(user_obj.email)
                # profile.user = user_obj.id
                profile.save()
                print(user.email)
                return HttpResponseRedirect(reverse_lazy('users:login'))
            except Exception as e:
                return HttpResponse('something as: {}'.format(e))

但我得到的错误是:

类似于:'UserForm' 对象没有属性 'id'

【问题讨论】:

  • 不,我需要user.id 用户对象的实际ID 才能传入profile
  • 您可以在views 中看到我正在尝试获取上面保存的用户的ID,因此根据我调用后的理解,目前不在request 中用户的save 应该提供id,即使用户是在数据库中创建的并带有一个ID。

标签: python django


【解决方案1】:

以下对我有用:

$ python manage.py shell
...
...

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user("test", password="test")
>>> user
<User: test>
>>> user.id 
3
>>> 

【讨论】:

    【解决方案2】:

    MultiModelForm 不是 Django 的一部分,您没有发布任何提供此类的项目的链接,但显然在这里:

    user = form['user']
    

    userUserForm 实例,而不是 User 模型实例。你想要的是这样的:

        # good naming is key to readable code...
        user_form = form['user']
        profile_form = form['profile']
    
        if user_type == 'Parent' or user_type == 'GC':
            c_id = generate_cid()
            user = user_form.save()
            profile = profile_form.save(commit=False)
            profile.user = user
            profile.customer_id = c_id
            profile.save()
            return HttpResponseRedirect(reverse_lazy('users:login'))
    

    还请注意,我删除了比无用更糟糕的 try/except 子句 - 在您的开发环境中,您希望让 Django 捕获这些错误并呈现更有用的调试页面(具有完整的回溯等),然后你想让 Django 捕获这些错误并返回 500 响应——如果你不干预,Django 默认会做这两件事。作为一般规则,如果您无法有效处理异常,则让它传播(不,当请求实际失败时返回 200 响应 - 并且可能泄漏一些内部信息 - 不符合“有效处理”的条件)。

    【讨论】:

    • 这里是MultiModelForm
    【解决方案3】:

    user.save() 将返回用户对象的实例。你可以用它来获取id

    【讨论】:

    • 我正在使用它,但它给出了错误,这就是问题所在。
    • 尝试做:u = user.save()profile.user = User.objects.get(id=u.id)
    • 另一个错误是NOT NULL constraint failed: users_parent.user_id
    • 我在上面的代码中没有看到任何users_parent 实例。这可能来自您添加 user_id 并带有约束 null=false 或根本没有提及 null 的模型。
    • 我已经添加了上面的User模型,请看一下!
    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 2011-12-23
    • 2010-10-26
    • 2014-11-30
    • 2018-10-03
    • 2012-06-15
    • 2013-06-14
    相关资源
    最近更新 更多