[英]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.