我正在尝试为我正在处理的Django应用实施用户帐户。我目前能够以管理员身份创建用户帐户,但我希望有一个表单,以便用户可以为自己创建一个帐户。我确实有一个表单视图来尝试这样做,但是当我点击提交时,数据不会写入数据库。我得到类似"[09/May/2015 20:41:00] "POST /createuser/ HTTP/1.1" 200 3175"
的东西......似乎应该发布。
我在Django 1.7.6中。我的工作基于this博客。
我的问题:当我尝试从公共视图创建用户帐户时,为什么我的数据不会写入数据库?
以下是相关部分:
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>
答案 0 :(得分:0)
正如我在评论中所说,您的表单无效,因此永远不会达到表单保存。但是在你的模板中,你已经避免了当表单无效时Django给你显示错误和重新显示值的所有东西,所以你无法看到它。您应该使用Django变量:
,而不是将字段写为原始HTML<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
继承,以确保保存散列密码。
答案 1 :(得分:0)
实际答案是我正在创建一个错误模型的视图。实际的用户创建发生在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})