【问题标题】:Django User CreationDjango 用户创建
【发布时间】:2017-09-04 23:50:16
【问题描述】:

我正在使用 Django 中的内置 UserCreationForm 进行基本用户创建。

这是我的views.py:

def user_register(request):
    if request.method == "POST":
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data['username']
            raw_password = form.cleaned_data['password1']
            user = User.objects.create_user(username=username)
            if raw_password:
              user.set_password(raw_password)
            else:
              user.set_unusable_password()
            user.save()
            return redirect('home')
    else:
        form = UserCreationForm()
        return render(request, 'registration/register.html', {'form':  form})

但是,在注册用户并被重定向到主页后,在我的管理页面中看到的用户数量并没有改变;没有创建用户。 知道我在这里做错了什么吗?

【问题讨论】:

  • 您问题中的缩进是错误的。修复它,因为它可能会导致问题。
  • 好的,这是明显的缩进,但我看不到 redirect 没有发生User.objects.create_user 发生的方式,我认为应该总是创建用户或引发异常。哦,你不需要调用set_unusable_password,当create_user中的密码为空时调用。此外,最后return 中的缩进应该是一个级别,因为当表单无效时。最后不用再调用user.save()了,create_user救了用户。
  • 实际上,我认为除了form.save()redirect 之外你不需要任何其他东西,因为you're not doing anything that the form doesn't do。无论如何,这并不能解释您的问题,它应该引发异常而不是重定向主页。

标签: python django


【解决方案1】:

试试:

from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
from django.contrib.auth.models import User

def user_register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            user=User.objects.create_user(username=username, password=password)
            user.save()
            #Below 2 lines, if you want user to get logged in
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect('home')
    else:
        form = UserCreationForm()
    return render(request, 'registration/register.html', {'form':  form})

【讨论】:

  • 试过这个..当我在管理页面中查看用户模型时仍然没有创建新用户
  • @SkillaPop,现在检查一下,我已经更新了我的答案
  • @SkillaPop 你一直说“当我在管理页面中查看用户模型时”。您确定没有创建用户吗?它可能是隐藏它的管理员中的过滤器吗?使用User.objects.count() 签入控制台。
  • 我刚刚检查了User.objects.count(),在我填写注册表之前它仍然是相同的号码
  • 是的,刚刚做了。。同样的,在用户模型中没有创建对象。
【解决方案2】:

不知道为什么你可以在不使用 create 的情况下重定向到 home,但你应该处理这种情况 form is not vaild 并从 form.is_valid() 块中删除 form.save() 如下:

form = UserCreationForm(request.POST)
if form.is_valid():
    # remove form.save()
    ....
else:
    print(form.errors.as_text())
    return render(request, 'registration/register.html', {'form':  form})

或像我一样覆盖 UserCreationForm 的保存方法:

def save(self, commit=True):
    user = super(UserCreationForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user

完整的演示是:

from django.views.generic import *
class RegisterView(FormView):
    template_name = 'registration/register.html'
    form_class = UserCreationForm
    success_url = reverse_lazy('home')

    def form_valid(self, form):
        form.save()
        return HttpResponseRedirect(self.get_success_url())

forms.py

class UserCreationForm(forms.ModelForm):
    error_messages = {
        'duplicate_username': u"duplicate username",
        'password_mismatch': u"password_mismatch",
        'duplicate_email': u'duplicate email'
    }

    username = forms.RegexField(
        max_length=30,
        regex=r'^[\w.@+-]+$',
        error_messages={
            'invalid': u"onlay can contaions symbol @/./+/-/_",
            'required': u"required"
        },
        label='username'
    )
    email = forms.EmailField(
        error_messages={
            'invalid': u"email invalid",
            'required': u'required'},
        label='email'
    )
    password1 = forms.CharField(
        widget=forms.PasswordInput,
        error_messages={
            'required': u"required"
        },
        label='password1 '
    )
    password2 = forms.CharField(
        widget=forms.PasswordInput,
        error_messages={
            'required': u"required"
        },
        label='password2'
    )

    def __init__(self, *args, **kwargs):
        super(UserCreationForm, self).__init__(*args, **kwargs)
        self.fields['username'].widget.attrs.update({'class': 'form-control'})
        self.fields['email'].widget.attrs.update({'class': 'form-control'})
        self.fields['password1'].widget.attrs.update({'class': 'form-control'})
        self.fields['password2'].widget.attrs.update({'class': 'form-control'})

    class Meta:
        model = User
        fields = ("username", "email")

    def clean_username(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        username = self.cleaned_data["username"]
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError(
            self.error_messages["duplicate_username"]
        )

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages["password_mismatch"]
            )
        password_validation.validate_password(password2)
        return password2

    def clean_email(self):
        email = self.cleaned_data["email"]
        try:
            User.objects.get(email=email)
        except User.DoesNotExist:
            return email
        raise forms.ValidationError(
            self.error_messages["duplicate_email"]
        )

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

【讨论】:

  • 有什么方法可以不用添加到我自己的 forms.py 中吗?我只是使用内置表单
  • 是的,你可以像现在一样在 form.is_vaild() 块中做这个工作人员,但是你需要处理表单无效
【解决方案3】:

我不知道你为什么要保存对象这么多次。正如here 所记录的,当在 UserCreationForm 实例中调用 form.save() 时,Django 将创建用户,设置密码(来自 password1 字段),将实例保存在数据库中并为您返回用户。所以 User.objects.create_useruser.save() 只会再次保存对象。

也许这不是您问题的解决方案,但您是否尝试过这样:

def user_register(request):
   form = UserCreationForm() 
   if request.method == 'POST':
       form = UserCreationForm(request.POST)
       if form.is_valid():
          user = form.save()
          # if you want to authenticate your user or log any info, do it here
          return redirect('home')
   # I wouldn't use the else statement here, so if there are errors in the form you probably want the same template to be rendered, in order to show the form errors to your user.
   return render(request, 'registration/register.html', {'form':  form})

【讨论】:

    【解决方案4】:

    感谢所有帮助我思考这个问题的人。当然,答案似乎比我想象的要简单得多。我的新user_register 视图是:

    from django.contrib.auth.forms import UserCreationForm
    from django.shortcuts import render, redirect
    
    def user_register(request):
       form = UserCreationForm(request.POST)
       if form.is_valid():
           form.save()
           return redirect('home')
       else:
           return render(request, 'registration/register.html', {'form':   form})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 2013-04-15
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 2017-12-21
      • 2012-07-14
      相关资源
      最近更新 更多