一、基础
- 1、创建项目
- 2、创建应用
- 3、数据模型
- 4、管理后台
- 5、路由
- 6、视图
- 7、网页模板
- 8、表单
- 9、django用户认证系统
二、进阶
- 1、数据模型,并注册到后台管理
- 2、网页模板
- 3、数据模型(所有数据) 显示到 网页模板
- 4、数据模型(单个数据) 显示到 网页模板
- 5、django用户认证系统
一、基础
- 1、Session 会话
- 2、ModelForm(表单)
- 3、ModelAdmin(管理后台)
三、高阶
一、基础 1、创建项目
pip install Django==3.0.4
django-admin startproject blog
python manage.py runserver
2、创建应用
- 2.1
python manage.py startapp article
- 2.2 项目/项目/setting.py里,INSTALLED_APPS注册APP
- 3.1 应用/models.py里,编写模型
- 3.2 项目/项目/setting.py里,DATABASES配置MySQL
- 3.3 使用Mysql创建数据库
mysql-u root -p
create database mrsoft库名 default character set utf8;
- 3.4 安装PyMySql驱动 pip install pymysql
- 3.5 项目/项目/__init __.py里,输入
import pymysql
pymysql.install_as_MySQLdb()
- 3.6
python manage.py makemigrations #生成迁移文件
python manage.py migrate #执行迁移
- 3.7
s1对象 = 表名.objects.create() #创建新记录
s2对象 = 表名.objects.all() #查询所有记录
s3对象 = 表名.objects.first() #获取第一条记录
s4对象 = 表名.objects.get(id=1) #获取id=1的记录
s5对象 = 表名.objects.order_by('字段名') # 从数据表中将按‘字段名’排序的对象读出
对象.save() #保存记录
表名.bojects.get(id=1).delete() #删除记录
外键:一对多,多(设置外键)
模型一 模型二(设置外键 '字段名' = models.ForeignKey(模型一名))
#通过模型一取模型二字段:
b = 模型一.objects.get(id=1)
r = b.模型二名_set.all() # Returns 模型二 的所有字段
#通过模型二取模型一字段:
b = 模型二.objects.get(id=2)
r = b.模型一.模型一字段
4、管理后台
- 4.1 创建超级用户
python manage.py createsuperuser
- 4.2 应用/admin.py里,绑定模型到UserAdmin管理后台
admin.site.register(models的模型, admin的模型)
- 4.3
from django.contrib import admin
from article.models import User,Article
class UserAdmin(admin.ModelAdmin):
"""
创建UserAdmin类,继承于admin.ModelAdmin
"""
# 配置展示列表,在User版块下的列表展示
list_display = ('username', 'email')
# 配置过滤查询字段,在User版块下右侧过滤框
list_filter = ('username', 'email')
# 配置可以搜索的字段,在User版块下右侧搜索框
search_fields = (['username','email'])
绑定User模型到UserAdmin管理后台
admin.site.register(User, UserAdmin)
5、路由
from django.urls import path,include
from django.contrib import admin
from django.shortcuts import render
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('article.urls')),
path('articles/', views.article_list),
path('articles////' , views.article_detail),
]
def article_list(request):
return HttpResponse('article_list函数')
6、视图
from django.shortcuts import render
from django.http import HttpResponse
from datetime import datetime
from django.views import View
7、网页模板
第一种:模板放在应用里
- 1 创建templates 文件夹在应用里,不需设置。
- 2 创建templates/应用名文件夹。
(在views.py引用时,填写 应用名/网页名.html,为了区分同一个html网页不同应用的情况) - 3 创建static 文件夹在应用里,不需设置。
|—css
|—fonts
|—images
|—js
第二种:模板放在项目里
创建templates 文件夹在项目里,需要settings.py中设置TEMPLATES修改
'DIRS': [os.path.join(BASE_DIR,'templates'),], #增加识别路径
- 7.1
{% extends "base.html" %} #继承base.html
{% block title %} 显示文字{% endblock %} #替换名叫title 的 block块
{% for article in articles %} 代码 {% endfor %} #循环
{{ article }} #来自view.py的同名参数 的值
{{ article.publish_date | date:'Y-m-d' }} # “|”右边是过滤器
- 7.2
#引用css外部文件
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}">
#引用js外部文件
<script src="{% static 'js/jquery.js' %}">script>
<script src="{% static 'js/bootstrap.js' %}">script>
- 7.3
<ul>
<li>无序列表列表项li>
ul>
8、表单
定义:将模型 通过表单 变为 模板上的表格
forms库
forms.Form类 表单系统的实现对象
forms.Field类 表单字段
forms.ModelForm类 表单模型
Form类 表单系统的实现对象
- 导入:
from django import forms.Form
- 属性:
as_p
作用:为表单字段提供<p>标签
例子:form.as_p
- 方法:
is_valid()
作用:验证表单数据是否正常
返回:True 代表正常,False代表异常
例子:表单名.is_valid()
Field类 表单字段
- 导入:
- 属性:
- 方法:
ModelForm类 表单模型
- 导入:
from django import forms.ModelForm
- 属性:
model
作用:指定模型对象,建立表单与数据表的关系
例子:model = 数据库表名
fields
作用:指定表单显示的字段,在网页会根据模型显示相应的表单表格
例子1:fields = ['模型字段1',['模型字段2',···]
例子2:fields = '__all__' #显示所有字段
labels
作用:指定网页<label>标签显示的信息
例子:labels = {'模型字段名':'网页显示信息'}
widgets
作用:网页小控件
例子:widgets = {'模型字段名': forms类.Textarea方法(attrs={'cols': 80})}
- 方法:
为了使用用户认证系统
在INSTALLED_APPS配置项中添加:
'django.contrib.auth': 包含认证框架的核心以及默认模型
'django.contrib.contenttypes':内容类型系统,用于给模型关联许可
在MIDDLEWARE配置项中添加:
'django.contrib.sessions.middleware.SessionMiddleware':通过请求管理会话
'django.contrib.auth.middleware.AuthenticationMiddleware':将会话和用户关联
- 9.1 用户模型
自带用户认证系统,进行用户认证的数据表为auth_user(用户的数据保存在这个表里)
在django.contrib.auth.models.py包中定义了class User(AbstractUser)类
User模型字段
下面依次对各字段进行说明:
id: 用户ID,主键,auto_increment
password: 密码(哈希值,元数据),Django 不储存原始密码,原始密码可以是任意长度的,包含任何字符
last_login: 缺省情况下设置为用户最后一次登录的日期时间
is_superuser: 布尔值,指明用户拥有所有权限(包括显式赋予和非显式赋予的)
username: 用户名,必选项,只能是字母数字(字母、数字和下划线),Changed in Django 1.2: 用户名现在可以包含 @ 、 + 、 . 和 - 字符
first_name: 可选项
last_name: 可选项
email: 可选项,电子邮件地址
is_staff: 布尔值,指明这个用户是否可以进入管理站点
is_active: 指明这个用户是否是活动的,建议把这个标记设置为False来代替删除用户账户,这样就不会影响指向用户的外键。
User模型方法
>>> from django.contrib.auth.models import User
>>> user= User()
>>> print(User)
<class 'django.contrib.auth.models.User'>
>>> u = User.object.get(username='l')
>>> print(u.is_authenticated) #测试用户是否经过验证的方法,总是返回True,验证用户是否合法
True
>>> print(u.get_full_name()) #返回first_name加上last_name,中间加一个空格
h r
>>> u.set_password('123') #设置用户密码,不保存 User 对象
>>> print(u.check_password('123')) #检查用户密码
True
>>> print(u.get_group_permissions(obj=None)) #通过用户的组,返回用户的一套权限
>>> print(u.get_all_permissions(obj=None)) #通过用户的组和用户权限返回用户的一套权限
- 9.2 用户注册
User模型在数据库中被命名为auth_user,使用migrate会自动生成
from django.contrib.auth.models import User
def regist(request):
name = request.POST.get('name')
password = request.POST.get('password')
User.objects.create_user(username=name, password=password)
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
# 这时,user是一个User类的实例,已经保存在了数据库内,你可以随时修改它的属性,例如:
>>> user.last_name = 'Lennon'
>>> user.save()
python manage.py createsuperuser #创建超级用户
- 9.3 用户登录和验证
Django在django.contrib.auth模块中提供了两个函数:
authenticate(username=要填, password=要填):用于验证指定用户的用户名和 密码
login(request, user) :用于在视图中登录用户
from django.shortcuts import render,redirect,HttpResponse
from django.contrib.auth import authenticate,login
def auth_view(request):
username=request.POST.GET("usernmae") # 获取用户名
password=request.POST.GET("password") # 获取用户的密码
user=authenticate(username=username,password=password) # 验证用户名和密码,返回用户对象
if user: # 如果用户对象存在
login(request,user) # 用户登陆,给某个已认证的用户附加上session_id信息
#登陆成功时,会生成一个sessionid保存在cookies中,在数据库django_session中查看
#当用户访问其他页面时,可以通过sessionid判断用户是否已经登陆。
return redirect("/index/")
else:
return HttpResponse("用户名或密码错误")
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# 重定向到一个登录成功页面。
else:
# 返回一个“帐户已禁用”错误信息。
else:
# 返回一个“非法用户名或密码”错误信息。
用户验证
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
在视图中认证用户
Django使用session和中间件关联请求对象中和认证系统。
每一次请求中都包含一个request.user属性,表示当前用户。
如果未登陆,该属性的值是一个AnonymousUser实例(匿名用户)
如果已登录,该属性就是一个User模型的实例。
可以使用is_authenticated方法进行判断,如下:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
使用认证系统的login()方法登录用户。
它接收一个HttpRequest参数和一个User对象参数。
该方法会把用户的ID保存在Django的session中。
下面是一个认证和登陆的例子:
```python
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# 跳转到成功页面
...
else:
# 返回一个非法登录的错误页面
...
- 9.4 登录要求装饰器
login_required()函数
实现以下功能
a)如果用户没有登录,那么就重定向到settings.LOGIN_URL,并且在查询字符串中传递当前绝对路径,例如:http://localhost:8000/account/login/?next=/blog/,/blog/为当前访问页面
b)如果用户已经登录,则正常的执行视图,视图代码认为用户已经登录
login_required()函数参数说明
(a)缺省情况下,成功登陆后重定向的路径是保存在next参数中
如果想换另外一个名称,可以使用第二个参数redirect_field_name,
将redirect_field_name=‘nextlink’,之前的链接会变成http://localhost:8000/account/login/?nextlink=/blog/,
注意,如果你提供了一个值给 redirect_field_name ,那么你最好也同样自定义 你的登录模板。
因为保存重定向路径的模板环境变量会使用redirect_field_name 作为关键值,而不使用缺省的 “next”
(b)login_url参数,可选,默认为settings.LOGIN_URL
举例:
#配置跳转路径,当用户未登陆访问其他页面时,自动跳转到登陆页面
#settings,py设置
LOGIN_URL = '/login/'
@login_required(redirect_field_name='nextlink')
def blog_title(request):
blogs = BlogModel.objects.all()
return render(request, 'titles.html', {'blogs':blogs})
#配置跳转路径,,当用户未登陆访问其他页面时,自动跳转到指定的url
url(r'^index/', login_required(views.index)),
url(r'^addstu/', login_required(views.addStu), name='astu'),
url(r'^stupage/', login_required(views.stuPage)),
- 9.5 用户登出
django.contrib.auth.logout() 来登出
from django.contrib.auth import logout
def logout(request):
if request.method == 'GET':
logout(request)
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect('/account/login/') #重定向到另一页
注意,被logout的用户如何没登录,不会抛出错误。
一旦logout,当前请求中的session数据都会被清空。
- 9.6 修改密码
django.contrib.auth.base_user.py包
set_password() 设置密码
check_password()检查密码
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new password')
u.save()
- 9.7 自定义User表
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE) # django自带用户表User模块和自定义的用户关联
name = models.CharField(max_length=32)
def __str__(self):
return self.name
二、进阶 1、数据模型,并注册到后台管理
- 1.1 编写models.py文件
例:
from django.db import models
# Create your models here.在这里创建模型
class Topic(models.Model): # 继承Django的models包的Midel模块
"""
用户学习的主题
模型会在数据库中映射出一个数据库表。
模型实际上是 *** 作数据库的。
文档链接 https://docs.djangoproject.com/zh-hans/2.2/topics/db/models/#fields
"""
text = models.CharField(max_length=200) # Topic的每一个属性都是数据库的一个字段
date_added = models.DateTimeField(auto_now_add=True) # 使用函数自动获取时间戳
def __str__(self):
"""返回模型的字符串表示"""
return self.text
- 1.2 创建数据表
python manage.py makemigrations learning_logs
python manage.py migrate
-
2.1 定义URL、编写视图、编写模板
-
2.2父模板和子模版
父模板
{% block content %}{% endblock content %}
子模板
{% extends "learning_logs/base.html" %}
{% block content %}
代替父模板的block content块
{% endblock content %}
3、数据模型(所有数据) 显示到 网页模板
流程:定义URL、编写视图、添加模板,均在APP应用里编写。
- 3.1 定义URL
path('topics/', views.topics, name='topics'),
- 3.2 编写视图
from .models import Topic
def topics(request):
"""显示所有主题"""
topics = Topic.objects.order_by('date_added') # 从数据库中将按data_added排序的Topic对象读出
content = {'topics': topics} # 按字典的形式将数据进行存储
return render(request,'learning_logs/topics.html',content)
输出参数: ‘topics’
- 3.3 添加模板
传入参数: topics
{% extends "app1indexF.html" %}
{% block content %}
<p>topicsp>
<ul>
{% for topic in topics %}
<li>{{ topic }}li>
{% endfor %}
ul>
{% endblock content %}
4、数据模型(单个数据) 显示到 网页模板
流程:定义URL、编写视图、添加模板,均在APP应用里编写。
- 4.1 定义URL
path('topics//' , views.topics, name='topics'),
输出参数: topic_id
- 4.2 编写视图
传入参数: topic_id
def topic(request,topic_id):
'''显示单个主题及其所有的条目'''
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
content = {'topic': topic, 'entries': entries} # 按字典的形式将数据进行存储
return render(request,'topic.html', content)
输出参数: ‘topic’ ‘entries’
- 4.3 添加模板
传入参数: ‘topic’ ‘entries’
topic:{{ topic }}
{% for entry in entries %}
{{ entry.date_added|date:'M d, Y H:i' }}
{{ entry.text|linebreaks }}
{% empty %}
No topics have been added yet.
{% endfor %}
5、django用户认证系统
- 5.1 自定义用户认证系统
Django 自带的用户认证系统已经可以满足大部分的情况,但是有时候我们需要某些特定的需求。
Django 支持使用其他认证系统、也可以扩展Django的User模块,完全自定义新的认证模块。
models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, email, name, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
name=name,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
name=name,
)
user.is_admin = True
user.save(using=self._db)
return user
class UserProfile(AbstractBaseUser):
'''账号表'''
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
name = models.CharField(max_length=32)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from customauth.models import MyUser
class UserCreationForm(forms.ModelForm):
"""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:
model = MyUser
fields = ('email', 'date_of_birth')
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 don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = MyUser
fields = ('email', 'password', 'date_of_birth', 'is_active', 'is_admin')
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"]
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'date_of_birth', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('date_of_birth',)}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'date_of_birth', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)
settings.py
AUTH_USER_MODEL = 'customauth.MyUser'
#customauth指APP name, MyUser指自定义的用户表model类
#(这个时候仍然可以使用django.contrib.auth import authenticate,login,logout 等认证方法,只是保存数据的表不一样)
一、基础 1、Session 会话
存储用户的登录状态
1.1 启动会话
sttings.py里,MIDDLEWARE=[ ‘django.contrib.sessions.middleware.SessionMiddleware’,]
1.2 配置会话引擎
1.3 使用会话实现登录功能
python manage.py shell
#创建新用户
>>> from django.contrib.auth.models import User
>>> User.objects.create_user(username='andy',password='mrsoft')
<User: andy>
#验证用户
>>> from django.contrib.auth import authenticate
>>> user= authenticate(username='andy',password='123456')
>>> user #密码错误,返回NONE
>>> user= authenticate(username='andy',password='mrsoft')
>>> user #密码正确,返回user对象
<User: andy>
#添加验证用户是否登录功能
@login_required
2、ModelForm(表单)
2.1 字段类型
2.2 验证
3、ModelAdmin(管理后台)三、高阶
版权声明:本文核心代码和内容均来自CSDN博主「Lmx!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hskjshs/article/details/113121750
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)