簡體   English   中英

Django用戶帳戶:根據模型創建視圖

[英]Django user accounts: creating view from model

我正在嘗試為我正在使用的Django應用程序實現用戶帳戶。 我目前能夠以管理員身份創建用戶帳戶,但是我想擁有一個表單,以便用戶可以自己創建一個帳戶。 實際上,我確實有一個表單視圖嘗試執行此操作,但是當我單擊“提交”時,數據不會寫入數據庫。 我收到類似"[09/May/2015 20:41:00] "POST /createuser/ HTTP/1.1" 200 3175" ...似乎應該在發布。

我在Django 1.7.6中。 我的工作基於博客。

我的問題 :嘗試從公共視圖創建用戶帳戶時,為什么我的數據沒有寫入數據庫?

以下是相關的部分:

models.py
    class AuthUserManager(BaseUserManager):
    def create_user(self, username, email, password=None):
        if not email:
            raise ValueError('Users must have an email address')
        if not username:
            raise ValueError('Users must have a username')

        user = self.model(username=username, email=self.normalize_email(email),
                          )
        user.is_active = True
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, password):
        user = self.create_user(username=username, email=email, password=password)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user


class AuthUser(AbstractBaseUser, PermissionsMixin):
    alphanumeric = RegexValidator(r'^[0-9a-zA-Z]*$', message='Only alphanumeric characters are allowed.')

    ### Redefine the basic fields that would normally be defined in User ###
    username = models.CharField(unique=True, max_length=20, validators=[alphanumeric])
    email = models.EmailField(verbose_name='email address', unique=True, max_length=255)
    first_name = models.CharField(max_length=30, null=True, blank=True)
    last_name = models.CharField(max_length=50, null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True, null=False)
    is_staff = models.BooleanField(default=False, null=False)

    ### Our own fields ###
    profile_image = models.ImageField(upload_to="uploads", blank=False, null=False, default="/static/images/defaultuserimage.png")
    user_bio = models.CharField(max_length=600, blank=True)

    objects = AuthUserManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def get_full_name(self):
        fullname = self.first_name+" "+self.last_name
        return fullname

    def get_short_name(self):
        return self.username

    def __unicode__(self):
        return self.email


forms.py
class AuthUserForm(UserCreationForm):
    class Meta:
        model = AuthUser
        fields = ['username', 'email', 'first_name', 'last_name', \
              'password','user_bio']



views.py
def AuthUserView(request):
    if request.method == 'POST':
        form = AuthUserForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            first_name = form.cleaned_data['first_name']
            last_name = form.cleaned_data['last_name']
            password1 = form.cleaned_data['password1']
            password2 = form.cleaned_data['password2']
            user_bio = form.cleaned_data['user_bio']

            authuser_obj = AuthUser(username = username,
                                    email = email,
                                    first_name = first_name,
                                    last_name = last_name,
                                    password1 = password1,
                                    password2 = password2,
                                    user_bio = user_bio
                                    )
            authuser_obj.save()
            return render_to_response('recipes/name.html', RequestContext(request))
    else:
        form = AuthUserForm()
    return render(request, 'recipes/name.html',
                  {'form' : form})




name.html
<form action="/createuser/" method="post">
      {% csrf_token %}

<h2>Create your account here!</h2>

<div class="form-group">
    <div class="col-sm-8">

        <label for="first_name" class="col-sm-6">First Name</label>
        <input type="text"  class="form-control" name="first_name" id="first_name"
               placeholder="First Name">
    </br>
        <label for="last_name" class="col-sm-6">Last Name</label>
        <input type="text"  class="form-control" name="last_name" id="last_name"
               placeholder="Last Name">

    </br>
        <label for="username" class="col-sm-6">Username</label>
        <input type="text"  class="form-control" name="username" id="username"
               placeholder="User Name">
    </br>
        <label for="email" class="col-sm-6">Email</label>
        <input type="text"  class="form-control" name="email" id="email"
               placeholder="Email">
    </br>
        <label for="password1" class="col-sm-6">Password</label>
        <input type="text"  class="form-control" name="password1" id="password1"
               placeholder="Keep it to just numbers and letters">
    </br>
        <label for="password2" class="col-sm-6">Enter your password again</label>
        <input type="text"  class="form-control" name="password2" id="password2"
               placeholder="Just to double check">
    </br>
        <label for="user_bio" class="col-sm-6">Care to share a bio?</label>
        <input type="text"  class="form-control" name="user_bio" id="user_bio"
               placeholder="Write a bit about yourself!">
    </br>
    <div class="col-sm-offset-3 col-sm-1">
        <button type="submit" class="btn btn-warning" name="submit" id="submit">Submit</button>
    </div>

</div>
    <a><img src="/static/recipes/images/beet4flipped.png" align="right" ></a>

    </div>

</div>


</form>

如我在評論中所述,您的表格無效,因此永遠不會保存表格。 但是在您的模板中,您避免了Django提供的所有操作,以顯示錯誤並在表單無效時重新顯示值,因此您無法看到它。 不應將字段寫為原始HTML,而應使用Django變量:

<div>{{ form.non_form_errors %}</div>

<div class="form-group">
    <div class="col-sm-8">
        {{ form.first_name.label }}
        {{ form.first_name }}
        {{ form.first_name.errors }}
    </div>

    <div class="col-sm-8">
        {{ form.last_name.label }}
        {{ form.last_name }}
        {{ form.last_name.errors }}
    </div>

... 等等。

請注意,您的視圖也過於復雜,並嘗試保存原始密碼。 你應該做這個:

def AuthUserView(request):
    if request.method == 'POST':
        form = AuthUserForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('some-destination-url-name')
    else:
        form = AuthUserForm()
    return render(request, 'recipes/name.html', {'form' : form})

因為無論如何,ModelForm都會根據清除后的數據創建實例; 特別是UserCreationForm你從電話繼承set_password上的新用戶,以確保哈希密碼被保存。

實際的答案是我創建的模型不正確。 實際的用戶創建發生在admin.py中,該文件未在上面顯示,但繼承自AuthUser。 請參考我提供的完整代碼鏈接。 模板完全相同,只是我將其重命名為signup.html。

admin.py
class CustomUserCreationForm(UserCreationForm):
    """ A form for creating new users. Includes all the required fields, plus a repeated password. """
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password Confirmation', widget=forms.PasswordInput)

    class Meta(UserCreationForm.Meta):
        model = AuthUser
        fields = ('username', 'email', 'first_name', 'last_name', 'user_bio')

    def clean_username(self):
        username = self.cleaned_data["username"]

        try:
            AuthUser._default_manager.get(username=username)
        except AuthUser.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

    def clean_password2(self):
        #Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")

        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords do not match.")
        return password2

    def save(self, commit=True):
        #Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class CustomUserChangeForm(UserChangeForm):
    password = ReadOnlyPasswordHashField(label="password",
                                         help_text="""Raw passwords are not stored, so there is no way to see this
                                         user's password, but you can change the password using <a href=\"password/\">
                                         this form</a>.""")

    class Meta(UserChangeForm.Meta):
        model = AuthUser
        fields = ('username', 'email', 'password', 'is_active', 'is_staff', 'is_superuser', 'user_permissions')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


views.py
def CustomUserCreationView(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect("/recipes/")
    else:
        form = CustomUserCreationForm()
    return render(request, 'recipes/signup.html',
                  {'form' : form})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM