Django学习记录第六天—依然是注册 + 登录
写了两篇的注册还没写完今天一定要写完,本想今天连同登录也一起写了,但是今天状态貌似不是很好,能写多少写多少吧。
OK,开始,上一篇末尾写到有些功能没有实现,如是否已注册问题,我们来处理一下。至于其他的问题,大家可以去查一查。这里不多做介绍了。
- 注册验证是否已经注册。
来更新一下post。为了不显得失败很突兀,我们将传入的email返回,然后显示。
def post(self, request):
form = RegisterForm(request.POST)
#我们刚才说过POST其实是个dict所以可以使用['']来取值,由于已经验证过,我们不需要使用get
password = request.POST['password']
email = request.POST['email']
if form.is_valid():
#通过Email来获取该对象查看是否存在
user = UserProfile.objects.filter(email=email)
if user is None:
user = UserProfile()
#对密码进行加密
user.password = make_password(password)
user.email = email
#保存信息
user.save()
#发送邮箱验证码
send_your_email(email)
return render(request, 'register.html', {
'username': email,
'form': form,
})
else:
return render(request, 'register.html', {
'username': email,
'msg': '账号已存在',
'form': form,
})
else:
return render(request, 'register.html', {
'username': email,
'error': form.errors,
'form': form,
})
html中我们只需要将msg加上,然后将username加上即可。
这是错误msg地方的代码修改。
<div class="form-group marb8 captcha1">
<label>验 证 码</label>
{{ form.captcha }}
</div>
<div class="error btns" id="jsEmailTips">{% for key, value in error.items %}{{ value }}{% endfor %}{{ msg }}</div>
#将{{ msg }}加在末尾即可。
username html代码修改
<div class="form-group marb20 ">
<label>邮 箱</label>
<input type="text" id="id_email" name="email" value="{% if username %}{{ username }}{% endif %}" placeholder="请输入您的邮箱地址" />
</div>
OK,这样我们可以看一下效果。
image.png
没毛病。
接下来我们要处理一个有意思的地方了。我们邮件已经发送,应该来激活一下了。
首先看一下我们收到的信息是什么。
image.png
OK首先来配置一下url。
这里我们直接来到TestProject下配置url
from users.views import RegisterActiveView
urlpatterns = [
...
...
url(r'active/(?P<name>.*)', RegisterActiveView.as_view(), name='register_active'),
]
这里我们再来看一下数据库里的状态
这里还是有必要说一下的 我们通过(?P<name>)来匹配需要的值,这里的name很重要,后面会用到!
image.png
我们发现刚注册完的账号,is_active为1。明显不对。所以我们在注册的时候需要将其改为False。
更新注册views.py,同时为了后期不报错,我们username也默认赋值为邮箱的值。
user = UserProfile()
# 对密码进行加密
user.password = make_password(password)
user.username = email
user.email = email
user.is_active = False
# 保存信息
user.save()
# 发送邮箱验证码
send_your_email(email)
return render(request, 'register.html', {
'username': email,
'form': form,
})
之后来写我们激活的view
class RegisterActiveView(View):
def get(self, request, name):
try:
validate_model = EmailValidateModel.objects.get(validate_code=name)
# 通过name获取到active对象,通过active对象得到email
email = validate_model.email
user = UserProfile.objects.get(email=email)
if user.is_active:
return render(request, 'active_result.html', {
'result': '激活失败!!!'
})
else:
user.is_active = True
user.save() #注意哦!这里还有个save操作!!
return render(request, 'active_result.html', {
'result': '激活成功!!!'
})
except:
return render(request, 'active_result.html', {
'result': '验证码错误!!!'
})
这里我们可以看到def get方法比之前多了一个name,这个name在哪来的呢?就是之前使用正则匹配到的。
这里,我使用的是UserProfile.objects.get由于get是精准查找,当找不到就会抛出异常,所以使用了try: except:,这里也可以使用filter,不过返回的是个数组,还需要再处理。看你们的习惯。
额,同事为了看激活状态我还在templates中添加了一个active_result.html,内容很简单。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证结果</title>
</head>
<body>
<span>{{ result }}</span>
</body>
</html>
看一下结果。
激活前
image.png
激活后
image.png
注册到这基本完成,之后就是登陆了。
来吧,登录开始。
写道登录我们可以来写一下我们的大体流程。
html先要弄好 --> 然后配置url --> 配置url你会发现你需要一个view --> 配置view的时候你会发现你需要model,也许还需要一个Form-->配置model-->配置Form。
这是我的一个思路。
- html
顺着这个思路,我们来看一下,收先处理一下html,跟register一样,这里我就不重复了替换../ 为 {% static '文件路径' %}
- url
我们来写一下我们的url。
来到users app下的urls配置一下。
urlpatterns = [
url(r'login/', LoginView.as_view(), name='login'),
...
]
- LoginView
我们来配置一下,我们的LoginView
class LoginView(View):
def get(self, request):
return render(request, 'login.html', {
})
这样,我们就可以看到我们的界面了,但是为了登录,我们发现我们需要使用post,同事还需要使用Form
先来写一下我们的Form。
- Form
class LoginForm(forms.Form):
username = forms.EmailField()
password = forms.CharField(min_length=8)
依然注意这里的username、password要与html中的name对应。
- 更新view
这里我们需要使用authenticate与login
def post(self, request):
form = LoginForm(request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
#激活后才能登录
if user is not None and user.is_active:
login(request, user)
return render(request, 'index.html',{
})
else:
return render(request, 'login.html', {
'msg': "密码或账号错误"
})
else:
return render(request, 'login.html', {
'errors': form.errors
})
- 更新一下 html
<div class="form-group marb8 ">
<label>密 码</label>
<input name="password" id="password_l" type="password" placeholder="请输入您的密码" />
</div>
<div class="error btns login-form-tips" id="jsLoginTips">{% for key, value in errors.items %}{{ value }}{% endfor %}{{ msg }}</div>
记得添加 {% csrf_token %}
与register一样 加上错误处理。
OK,到这里登录就算是结束了。
正好有点时间,我们来看看model的操作。大家可能对model.objects.[get/filter/all/order_by]感到奇怪,我们来看一下这些都是写什么操作。文档地址
- objects
image.png
每当你创建一个model,Django就会自动给你提供一个抽象的数据库API让你查询、删除、查询、更新object。
- save()
当你创建了一个object,只需要执行save()就可以保存它。
同时,如果你想修改一个object,如 user.username='haha',修改后你只需要一个save()就OK了。
- 查询
如果你想想查询呢,你需要先通过manager来创建一个QuerySet然后通过这个QuerySet来获取objects,然后文档中有这么一句话(Each model has at least one Manager, and it’s called objects by default.)
每个model默认有至少一个Manager默认叫做objects。
也就是我们通过objects这个manager然后使用all() get()等获取到QuerySet,我们来验证一下。在view.py中加这么一句话.
class LoginView(View):
def get(self, request):
user = UserProfile.objects.all()
return render(request, 'login.html', {
})
我们来看一下user是什么类型。
image.png
我们可以看到user是QuerySet类型,这就没问题了。
- filter
这个可以看成是筛选,返回值是多个值。我们可以用for对其进行操作。有意思的是文档给我们写了这么一种形式。
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime(2005, 1, 30)
... )
文档解释是(The result of refining a QuerySet is itself a QuerySet, so it’s possible to chain refinements together.)返回结果是QuerySet的时候,可以继续连接。
- get
这个返回一个值,唯一值,但是文档有句话我们需要注意一下(If there are no results that match the query, get() will raise a DoesNotExist
exception.)如果这里没有结果返回,将会抛出一个DoesNotExist异常哦>
其他的我们后期遇到在说。今天就到这里了