Django-保存用户后获取用户ID [英] Django - get user id after saving the user

查看:58
本文介绍了Django-保存用户后获取用户ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我到目前为止尝试过的:

来自 models.py :

  class User(AbstractBaseUser,PermissionsMixin):email = models.EmailField(max_length = 254,unique = True)标题= models.CharField(max_length = 255,blank = False)user_type = models.CharField(max_length = 255,options = USER_TYPE,blank = False)性别= models.CharField(max_length = 255,options = CHOICES,blank = False)内容= models.CharField(max_length = 255,blank = True)is_staff = models.BooleanField(默认= False)is_superuser = models.BooleanField(默认= False)is_active = models.BooleanField(默认= True)last_login = models.DateTimeField(null =真,空白=真)date_joined = models.DateTimeField(auto_now_add = True)USERNAME_FIELD ='电子邮件'EMAIL_FIELD ='电子邮件'REQUIRED_FIELDS = ['password']对象= UserManager()def get_absolute_url(self):返回"/users/%i/"%(self.pk)类Parent(models.Model):用户= models.OneToOneField(用户,on_delete = models.CASCADE)contact_email = models.EmailField(空白=假)customer_id = models.BigIntegerField(blank = False)contact_no = PhoneNumberField(空白= True,help_text ='电话号码必须输入到''格式:\'+ 999999999 \'.最多允许15位数字.')collection_use_personal_data = models.BooleanField(blank = False) 

来自 forms.py :

  class ParentForm(forms.ModelForm):类Meta:模特=父母字段=('contact_email','contact_no','collection_use_personal_data')类UserParentForm(MultiModelForm):form_classes = {用户":UserForm,个人资料":ParentForm} 

来自 views.py :

  def post(自己,请求,* args,** kwargs):打印(request.POST)user_type = request.POST.copy()['user-user_type']形式=无如果user_type =='PB':形式= UserBelow18Form(request.POST)elif user_type =='PA':表格= UserAbove18Form(request.POST)elif user_type =='父母':形式= UserParentForm(request.POST)打印(已选择用户-父级表单")elif user_type =='GC':形式= UserGCForm(request.POST)如果form.is_valid():用户=形式['用户']个人资料=形式['个人资料']如果user_type =='Parent'或user_type =='GC':c_id = generate_cid()profile.customer_id = c_idprint(为父级或GC生成的'id:{}'.format(c_id))尝试:user.save()profile.user = User.objects.get(id = user.id)#打印(user_obj.email)#profile.user = user_obj.idprofile.save()打印(user.email)返回HttpResponseRedirect(reverse_lazy('users:login'))例外,例如e:返回HttpResponse('something as:{}'.format(e)) 

但是我得到的错误是:

类似:"UserForm"对象没有属性"id"

解决方案

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

  user = form ['user'] 

user UserForm 实例,而不是 User 模型实例.您想要的是这样的:

 #好的命名是可读代码的关键...user_form = form ['user']profile_form = form ['profile']如果user_type =='Parent'或user_type =='GC':c_id = generate_cid()用户= user_form.save()profile = profile_form.save(commit = False)profile.user =用户profile.customer_id = c_idprofile.save()返回HttpResponseRedirect(reverse_lazy('users:login')) 

还请注意,我删除了比没用更糟糕的try/except子句-在您的开发环境中,您要让Django捕获这些错误并呈现更有用的调试页(具有完整的追溯等),然后生产时,您要让Django捕获这些错误并返回500响应-如果您不干预,默认情况下Django都会这样做.通常,如果您不能有效地处理异常,请让其传播(不,不可以,当请求实际失败时返回200响应-可能泄漏一些内部信息-不属于有效处理").

I'm working on a project using Python(3.7) and Django(2.2) in which I have implemented models for multiple type of users and combined models by using MultiModleForm to display as a single form on front end, after that when I try to create a user in view and call the save method for user model and try to get its id but it's giving an error.

Here's what I have tried so far:

From 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)

From 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
    }

From 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))

But I'm getting the error as:

something as: 'UserForm' object has no attribute 'id'

解决方案

MultiModelForm isn't part of Django and you didn't post a link to whatever project provides this class, but obviously here:

user = form['user']

user is the UserForm instance, NOT the User model instance. What you want is something like:

    # 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'))

Also note that I removed your try/except clause which was worse than useless - in your dev environment you want to let Django catch those errors and render the much more useful debug page (which has the full traceback etc), and on production you want to let Django catch those errors and return a 500 response - both thing Django does by default if you don't interfere. As a general rule, if you cannot effectively handle an exception, let it propagate (and no, returning a 200 response when the request actually failed - and possibly leaking some internal informations - doesn't qualify as "effective handling").

这篇关于Django-保存用户后获取用户ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆