在线编程网站开发教程:第三讲 数据模型和用户认证

发布一下 0 0

一、选用数据库系统postgresql

安装与使用postgresql

#安装apt updateapt install postgresql#配置serveice postgresql statussudo su postgrespsqlpostgres=# \l; #显示数据库postgres=# \du; #显示用户#修改用户postgres的密码postgres=# alter user postgres with password 'yourpasswd';#创建新用户,并设置权限postgres=# create user wuxc with password 'mypasswd';postgres=# alter user wuxc with superuser;#创建数据库,隶属用户wuxcpostgres=# create database lichee-wuxc owner wuxc;#以新用户登录数据库psql -u wuxc -d lichee-wuxc

常见问题:

Q:为什么用postgresql
A:因其免费、开源、易用,还有图形界面pgadmin4
Q: initdb faild: removing contents of data directory "/var/lib/postgresql/13/main"
A: su postgres && pg_createcluster 13 main --start
Q: private key file "/etc/ssl/private/ssl-cert-snakeoil.key" has group or world access,File must have permissions u=rw (0600)
A: chmod 600 /etc/ssl/private/ssl-cert-snakeoil.key
Q:where the config file?
A:(1)配置文件 **/etc/postgresql/13/main**
(2)数据文件 **/var/lib/postgresql/13/main/**
Q:how to remote connect to db ?
A: (1)修改 配置文件夹下的 postgresql.conf ,将 #listen_addresses = 'localhost' 修改为 listen_addresses = '*';
(2)修改 配置文件夹下的 ***pg_hba.conf***,增加一行:
host all all 0.0.0.0/0 md5
Q:Peer authentication failed for user 'wuxc'?
A:修改配置文件pg_hba.conf,替换 peer 为 md5,重启数据库:sudo service postgresql restart

二、django根据数据库生成模型类

在数据库已有数据表的情况下,在不影响数据的情况下使用模型,方法如下:

1. 设置settings.py配置数据库信息

DATABASES = {'sqlite3': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',},'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2','NAME': 'lichee-wuxc', # 数据库名称'USER': 'wuxc', # 登录数据库用户名'PASSWORD': 'yourpassword', # 登录数据库密码'HOST': '127.0.0.1', # 数据库服务器的主机地址'PORT': '5432', # 数据库服务的端口号},}

2. 反向生成模型

python manage.py inspectdb > mymodels.py

3. 修正模型

  • 模型名:可根据自己需求进行修改
  • 模型所属app:根据自己需求进行分配,这里全部放在主应用almond中
  • 模型外键引用:将所有使用ForeignKey的地方,模型都改成字符串,这样就不会产生模型顺序的问题。另外,如果引用的模型已经移动到其他app中了,那么还要加上这个app的前缀
  • 让django管理模型:将Meta下的managed=False删掉,如果保留这个,那么以后对模型的任何修改,使用migrate都不会映射到数据库
  • 表名:切记不要修改表的名字db_table,不然映射到数据库中,会发生找不到对应表的错误
  • 外键级联关系:根据自己实际情况进行修改,举一例:
esid = models.ForeignKey(Student, to_field="sid", on_delete=models.CASCADE, db_column='esid', related_name='stu_exam_paper')

4. 初始化

1) 执行python manage.py makemigrtaions生成初始化的迁移脚本。

2) 执行python manage.py migrate --fake-initial,运行迁移脚本

5. 数据库映射

1) 每次对模型修改后,都要执行python manage.py makemigrtaions

2) 再执行python manage.py migrate 保持模型与数据库才能一致。

三、在项目中使用数据模型

1、管理数据库

在主应用almond中创建两个文件件models.py及admin.py

# models.py中的部分模型class Pyoperate(models.Model):   passclass Zonghe(models.Model):	passclass Student(AbstractBaseUser):  stugrade = (('高一年级','高一年级'),('高二年级','高二年级'),('高三年级','高三年级'))  stuclass = tuple( (str(v) +'班', str(v)+'班') for v in range(1,20) )  sid = models.AutoField(verbose_name = '唯一号',primary_key=True)  sname = models.TextField(verbose_name = '姓名')  sno = models.TextField(verbose_name = '学号', unique=True)  sclass = models.TextField(verbose_name = '班级', choices=stuclass )  sgrade = models.TextField(verbose_name = '年级', choices=stugrade )  password = models.TextField(verbose_name = '密码',default='123321')  email = models.TextField(verbose_name = 'email', default='')  first_name = models.TextField(verbose_name = '姓', default='')  last_name = models.TextField(verbose_name = '名', default='')  is_staff = models.TextField(verbose_name = '在册', default=True)  is_active = models.BooleanField(verbose_name = '激活',default=True)  last_login = models.DateTimeField(verbose_name = '最后登录',default=datetime.now(),blank=True)  date_joined = models.DateTimeField(verbose_name = '注册时间',default=datetime.now(), blank=True)#almond中admin.py中的代码  from django.contrib import admin  from django.utils.translation import gettext_lazy as _  from .models import *      @admin.register(Student)  class StudentObj(admin.ModelAdmin):    list_display = ['sno','sname','sclass','sgrade','last_login','date_joined']    list_per_page = 50    fieldsets = (    ('Basic info', {"fields": ('sno','password'), }),    (_('Personal info'), {"fields": ('sname','sclass','sgrade', ), }),    (_('Permissions'), {"fields": ('is_active', ), }),    (_('Important dates'), {"fields": ('date_joined', ), }),    )    admin.site.register([Choicetimu, Pyoperate,......])

在admin.py中注册数据模型就可以利用django的admin应用对数据库进行CRUD的操作了。

https://blog.sina.com.cn/s/blog_9766a3620102yz1l.html

浏览记录

https://blog.sina.com.cn/s/blog_9766a3620102yz1l.html

修改记录

你会发现,模型Student的定义和注册与其他模型是不同的,定义时它继承了AbstractBaseUser类,注册时继承了admin.ModelAdmin类。这是因为Student除了增查改删外,还有学生登录认证的任务。其他用户使用django的admin应用默认的user表来认证管理。用Student来管理学生登录,还有一些工作要做:

#在settings.py文件中,增加第一行负责学生在前台登录认证,第二行是系统用户登录认证功能。AUTHENTICATION_BACKENDS = [  'almond.views.CustomModelBackend' ,  'django.contrib.auth.backends.ModelBackend',]

在almond.views中创建CustomModelBackend类,新建authencitate和get_user方法:


class CustomModelBackend(ModelBackend):	def authenticate(self, request, stuname=None, stunumber=None, **kwargs):	try :		student = Student.objects.get( Q( sno=stunumber) & Q( sname=stuname ) )		if student:			return student		except Exception :			return None	def get_user(self,user_id):		try:			return Student.objects.get(Q(sid=user_id))		except Student.DoesNotExist :			return None

2、用户登录

1) 后端代码,看注释


#定义表单模型class loginForm(forms.Form):	stuname = forms.CharField(label="姓 名:", max_length=128,widget=forms.TextInput(attrs={'class': 'form-control'}))	stunumber = forms.CharField(label="学 号:", max_length=128,widget=forms.TextInput(attrs={'class': 'form-control'}))#登陆def login(request):	if request.method == "POST":		login_form = loginForm(request.POST)#用提交数据定义登录表单模型对象		message = '请检查填写内容!'		if login_form.is_valid():			studentname = login_form.cleaned_data['stuname']			studentnumber = login_form.cleaned_data['stunumber']			#用自定义的认证方法验证用户			student = authenticate(stuname = studentname, stunumber = studentnumber)			if student:				auth_login(request, student)#登录成功会保存用户信息到request				return redirect('/pygram/')			else:				return render(request, 'login.html', locals())  #以下是get方法返回客户端  login_form = loginForm() #定义空的登录表单对象渲染到客户端  return render(request, 'login.html', locals())#登出,request 会清除当前用户登录信息@login_required(login_url='/login/')def logout(request):	auth_logout(request)	return redirect('/login/')

2) 前端代码,看注释

<!-- 在模板文件夹templates中创建login.html --><!DOCTYPE html><html><head><meta charset="UTF-8"><title>登陆</title><!-- 使用bootstrap5,css文件放在头部,js文件放在最后 --><link href="/static/bootstrap5/css/bootstrap.css" rel="stylesheet"></head><body><div style="margin: 15% 25%;"><h2 class="text-center"> 欢 迎 登 陆 </h2><form action="/login/" method="post">{% if message %}<!-- 认证不过时的提示信息 -->	<div class="alert alert-warning">{{ message }}</div>{% endif %}{% csrf_token %}<!--django安全策略防止跨域攻击 --><div class="form-group"><!-- 显示表单 -->{{ login_form.stuname.label_tag }}{{ login_form.stuname}}</div><br /><div class="form-group">{{ login_form.stunumber.label_tag }}{{ login_form.stunumber }}</div> <br /><input type="submit" class="btn btn-primary pull-right" value="提交"></form></div><script src="/static/bootstrap5/js/bootstrap.js"></script></body></html>
https://blog.sina.com.cn/s/blog_9766a3620102yz1l.html

第三讲就到这里。
第一讲 用Django创建在线编程网站项目
第二讲 Django创建应用webcoding,实现在线编程

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/82695.html