如何正确扩展django用户模型

时间:2019-06-18 07:33:51

标签: django authentication

在这里,我尝试将配置文件模型字段与用户模型字段一起添加。但是它不起作用,不会添加配置文件模型数据。但是after adding当我确实更新用户时,我可以同时更新两个模型{ {1}}和user在一起。但是在注册用户时,我无法添加profile模型数据。是否可以一次将概要模型数据与用户模型一起添加?

  

models.py

profile
  

forms.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100,blank=True,null=True)
    last_name = models.CharField(max_length=100,blank=True, null=True)
    location = models.CharField(max_length=100,blank=True, null=True)
    phone = models.CharField(max_length=20,blank=True,null=True)
    image = models.ImageField(upload_to='user image',default='default.jpg')


    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            Profile.objects.create(user=instance)

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.profile.save()
  

views.py

class RegisterForm(UserCreationForm):
    first_name = forms.CharField(max_length=100, required=False)
    last_name = forms.CharField(max_length=100, required=False)
    location = forms.CharField(max_length=100, required=False)
    phone = forms.CharField(max_length=20, required=False)
    image = forms.FileField(required=False, initial='default.jpg')

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise ValidationError('Email Already Exists')

        return email

    class Meta:
        model = User
        fields = ['username', "email", "password1", "password2",'first_name','last_name','location','phone','image','is_superuser', 'is_staff', 'is_active']
  

add_user.html

def add_user(request):
    if request.method == "POST":
        form = RegisterForm(request.POST or None,request.FILES or None)
        if form.is_valid():
            user = form.save(commit=False)
            user.save()
            messages.success(request, 'user created with username {}'.format(user.username))
            return redirect('list_user')
    else:
        form = RegisterForm()
    return render(request, 'add_user.html', {'form': form})

def update_user(request, id): #the problem while  updating is if i don't select the new image then it saves the default image.But other works fine
    user = get_object_or_404(User, id=id)
    if request.method == 'POST':

        form = EditRegisterForm(request.POST or None,request.FILES or None,instance=user)
        if form.is_valid():
            phone = form.cleaned_data['phone']
            location = form.cleaned_data['location']
            image = form.cleaned_data['image']
            first_name = form.cleaned_data['first_name']
            last_name = form.cleaned_data['last_name']
            user = form.save(commit=False)
            user.profile.phone = phone
            user.profile.location = location
            user.profile.first_name = first_name
            user.profile.last_name = last_name
            user.profile.image = image
            user.save()
            messages.success(request, ' {}  updated.'.format(user.username))
            return redirect('list_user')

2 个答案:

答案 0 :(得分:1)

与其按照自己的逻辑尝试, 考虑在您的视图中使用@ transaction.atomic装饰器。

如果发生任何异常,什么都不会保存到您的数据库中 此处的文档:https://docs.djangoproject.com/en/2.2/topics/db/transactions/#django.db.transaction.atomic

然后您可以简单地执行以下操作:

# remove your signals first, they're not required if you manually create the profile here

@transaction.atomic
def add_user(request):
    if request.method == "POST":
        form = RegisterForm(request.POST or None,request.FILES or None)
        if form.is_valid():
            user = form.save(commit=False)
            user.save()
            Profile.objects.create(
                user=user,
                first_name=form.cleaned_data['first_name'],
                #...and other attributes
            )
            messages.success(request, 'user created with username {}'.format(user.username))
            return redirect('list_user')
    else:
        form = RegisterForm()
    return render(request, 'add_user.html', {'form': form})```

答案 1 :(得分:1)

嗯,您已经通过信号创建了Profile。那么为什么不这样使用它呢?

def update_user(request, id):
    # Some code
    if form.is_valid():
        phone = form.cleaned_data['phone']
        location = form.cleaned_data['location']
        image = form.cleaned_data['image']
        first_name = form.cleaned_data['first_name']
        last_name = form.cleaned_data['last_name']
        user = form.save()
        user.refresh_from_db()
        user.profile.phone = phone
        user.profile.location = location
        user.profile.first_name = first_name
        user.profile.last_name = last_name
        user.profile.image = image
        user.profile.save()
        messages.success(request, ' {}  updated.'.format(user.username))
        return redirect('list_user')

我正在使用refresh_from_db()重新加载对象。由于Profile是通过信号创建的,因此刷新User对象应重新加载Profile模型。