我是连人,本期我们讲实现用户的注册和登录功能。
你无论开发什么网站,用户的注册和登录是必备的功能(除非你打算开发一个静态网站)。
我们将用户定义为一个“类别”(class),在class里面我们定义一些关于你的网站的用户的基础属性(比如购物网站要有用户余额,餐厅的网站可能要记录这个客户来吃过几次饭)。
Django中自带用户类,但是我不推荐使用,因为无法定义我上述的你需要的特别的属性。
对于用户的注册和登录,是对数据库和网站开发相连接的基础。不止用户的数据要靠class实现,例如用户发的消息,餐厅网站中菜的信息,购物网站商品的信息,都是通过class定义记录进数据库的。
由于Django强大的功能(此处指ORM功能),操作数据库的时候,我们也不必学习复杂的SQL语句了。
话不多说,直接开冲。
models.py是我们定义class的地方
from django.db import models
class User(models.Model):
username = models.CharField(max_length=10, unique=True)
password = models.CharField(max_length=10)
def __str__(self):
return self.username
class Meta:
ordering = ['id']
# ordering = ['-id'] 这个是降序的写法
这是一个最简单的User类,我只使用了用户名和密码。后面的完整性约束条件大家都懂嘤语我就不解释了。
CharField是定义这个变量是什么类型的函数。models类下常用的field大概有如下:
Field | 类型 |
---|---|
AutoField | 自增,一般是models自动创建了id=AutoField(primary_key=True) |
BooleanField | 布尔型 |
CharField | 字符型 |
DateField | 日期型 |
DateTimeField | 日期+时间类型 |
FloatField | 浮点型 |
IntegarField | 整型 |
TextField | 长文本型 |
一般常用的就是这些,像什么FileField可以直接用CharField记录储存地点,URLField什么的也是直接用CharField记录就可以。
下面简单介绍Field中的字段
字段 | 赋值 | 作用 |
---|---|---|
null | True or False | 可否为null值 |
blank | True or False | 可否为空 |
choice | 你自己建立的字典 | 将变量限定在一个范围 |
default | 符合Field规则的值 | 设定默认值 |
editable | True or False | 是否在admin界面里显示 |
primary_key | True or False | 设定主键 |
unique | True or False | 设定是否可以重复 |
(null和blank那里我也没太搞清楚,我一般用null)
str那里可以在admin界面(这篇文章下面会介绍)显示你需要显示的字段
class Meta里的ordering指排序顺序,引号里的值是你希望的排序的依据。
在admin.py中输入如下:
from . import models
admin.site.register(models.User)
这一步的目的是在admin界面中注册你需要用到的class。
然后,再在命令行中输入如下:
python manage.py makemigrations
python manage.py migrate
成功后应该如下图;
之后注册超级管理员,超管是我们登入后台的用户。输入如下命令:
python manage.py createsuperuser
创建过程如下:
(最开始的时候我还以为密码没输进去,结果是人家特意隐藏了……)
接下来打开服务器,进入127.0.0.1:8000/admin
输入我们刚刚创建的用户:
看到如下界面:
圈出来的就是我们刚才注册的User类。感兴趣的自己再进去看看长啥样,我就接下来讲本篇的重头注册和登录了。
因为用户的注册和登录需要密码或者更多的隐私信息,所以我们使用form表单以POST的方法从前端传递数据。
如果用户每次操作都要登录,用户肯定十分厌倦。这与“客户就是爹”的理念明显相悖。所以我们使用session记录用户是否登录,用户再做操作时也不必重新输入用户名和密码。
使用session来记录经我的服务器跑过,是可以处理两台电脑上登录不同的号的并行问题的。我没有用过cookie,具体情况请自行探索。
views.py
from CSDN import models
def home(request):
login_name = ''
if request.session.get('id'):
user = models.User.objects.get(id=request.session.get('id'))
login_name = user.username
return render(request, 'Home.html', {"name": login_name})
def login(request):
if request.session.get('id') != None: # 只有不在登录状态时才可以进行登录
return redirect('/')
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username and password:
username = username.strip() # 除去空格和换行
password = password.strip()
try:
user = models.User.objects.get(username=username)
except:
message = '该用户名不存在'
return render(request, 'Login.html', {"message": message})
if user.password == password:
request.session['id'] = user.id # 记录用户已登录
return redirect('/')
else:
message = '密码错误'
return render(request, 'Login.html', {"message": message})
return render(request, 'Login.html')
def register(request):
if request.session.get('id') != None: # 只有不在登录状态时才可以进行注册
return redirect('/')
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
username = username.strip() # 除去空格和换行
password = password.strip()
if models.User.objects.filter(username=username).exists():
message = '该用户名已被注册'
return render(request, 'Register.html', {"message": message})
user = models.User()
user.username = username
user.password = password
user.save()
request.session['id'] = user.id # 记录用户已登录
return redirect('/')
return render(request, 'Register.html')
def logout(request):
request.session.flush()
return redirect('/')
home.html
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<a href="../login">login</a>
<br/>
<a href="../register">register</a>
<br/>
{% if name %}
<p>Hello {{ name }}</p>
<br/>
<a href = "../logout">logout</a>
{% endif %}
</body>
</html>
register.html
<!DOCTYPE html>
<html>
<head>
<title>register</title>
</head>
<body>
<form action="/register/" method="post">
{% csrf_token %}
<input type="text" name="username"/>
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<a href="../">back to home</a>
<br/>
<a href="../login/">go to login</a>
{% if message %}
<script type="text/javascript">
alert("{{message}}");
</script>
{% endif %}
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/login/" method="post">
{% csrf_token %}
<input type="text" name="username"/>
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<a href="../">back to home</a>
<br/>
<a href="../register/">go to register</a>
{% if message %}
<script type="text/javascript">
alert("{{message}}");
</script>
{% endif %}
</body>
</html>
大家可以测试一下,我本地这里是没有问题的。
下一篇跟大家进一步分享关于class里的那些事,比如choice,foreign_key,笛卡儿积的问题。
转载注明出处