提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
pip install django
E:\python3.10
- python.exe
- Scripts
- pip.exe
- django-admin.exe 【工具,创建django项目中的文件和文件夹】
- Lib
- 内置模块
- site-packages
- openpyxl
- python-docx
- flask
- django 【框架的源码】
django中项目会有一些默认的文件和默认的文件夹。
打开终端。
进入某个目录(项目放在哪里)。
/Users/word/PycharmProjects/myapps
执行命令创建项目
"c:\python3.10\Scripts\django-admin.exe" startproject 项目名称
# 如果已加入环境系统环境变量。
django-admin startproject 项目名称
注意:
- Python解释器安装目录:E:\python\python.exe
- E:\Workspace\PythonWorkspace\StudyDjango\pythonProject --(基于Django创建的项目)
特殊说明:
命令行,创建的项目是标准的。
pycharm,在标准的基础上默认给咱们加了点东西。
默认项目的文件介绍:
mysite
├── manage.py 【项目的管理,启动项目、创建app、数据管理、导数据到数据库】【不要动】【***常常用***】
└── mysite
├── __init__.py
├── settings.py 【项目的配置文件】 【***常常修改***】
├── urls.py 【URL和函数的对应关系】【***常常使用***】
├── asgi.py 【接收网络请求】【不需要动】
└── wsgi.py 【接收网络请求】【不需要动】
我们开发比较简洁,用不到多app,一般情况下,项目下创建1个app就够了。
├── myapp
│ ├── __init__.py
│ ├── admin.py django默认提供了admin后台超级用户管理。
│ ├── apps.py app启动类,不用管
│ ├── migrations 数据库变更记录
│ │ └── __init__.py
│ ├── models.py 【**很重要**】,对数据库操作,经常使用。
│ ├── tests.py 单元测试我们现在不使用
│ └── views.py 【**很重要**】,函数。
├── manage.py
└── Studys
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py 【URL->路由配置】
└── wsgi.py
python manage.py startapp myapp
python manage.py runserver
运行运行网页出现成功
STATIC_URL = '/static/'
/static/my_app/myexample.jpg
{ % load static from staticfiles % }
<img src="{ % static "my_app/myexample.jpg" % }" alt="My image"/>
变量输出语法:把变量的数据输出到模版中
{ { var } }
语法:
{ % tag % }
作用:在输出中创建文本控制循环或逻辑加载外部信息到模板中
语法:
{ % for ... in ... % }
循环逻辑
{ % endfor % }
语法:
{ % if ... % }
逻辑1
{ % elif ... % }
逻辑2
{ % endif % }
语法:
{ % comment % }
多行注释
{ % endcomment % }
语法:
{ % include "base/index.html" % }
语法:
{ % url 'name' p1 p2 % }
{ % csrf_token % }
语法:
{ { 变量|过滤器 } },例如{ { name|lower } },表示将变量name的值变为小写输出
关闭HTML自动转义
{ { data|safe } }
可以在if标签中使用过滤器结合运算符
if list1|length > 1
过滤器能够被“串联”,构成过滤器链
name|lower|upper
date:根据给定格式对一个date变量格式化
value|date:'Y-m-d'
使用管道符号 (|)来应用过滤器
通过使用过滤器来改变变量的计算结果
pip install mysqlclient
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day7',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PATH': 3306
}
}
字段:
AutoField:一个根据实际ID自动增长的IntegerField,通常不指定
如果不指定,一个主键字段将自动添加到模型中
CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput,一定要设置max_length的长度,否则报错
TextField:大文本字段,一般超过4000使用,默认的表单控件是Textarea
IntegerField:整数
DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数
FloatField:用Python的float实例来表示的浮点数
DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示的日期
TimeField:使用Python的datetime.time实例表示的时间,参数同DateField
DateTimeField:使用Python的datetime.datetime实例表示的日期和时间,参数同DateField
表关联:
ForeignKey:一对多,将字段定义在多的端中
ManyToManyField:多对多,将字段定义在两端中
OneToOneField:一对一,将字段定义在任意一端中
# 雇员信息表
class Employee(models.Model):
emp_id = models.CharField(max_length=15, verbose_name='雇员ID')
emp_name = models.CharField(max_length=20, verbose_name='雇员姓名')
phone = models.CharField(max_length=20, verbose_name='雇员电话')
address = models.TextField(verbose_name='雇员地址')
company = models.CharField(max_length=20, verbose_name='所属子公司')
department = models.CharField(max_length=20, verbose_name='部门')
class Meta():
db_table = 'employee'
python manage.py makemigrations
python manage.py migrate
以后在开发中如果想要对表结构进行调整:
在models.py文件中操作类即可。
命令
python manage.py makemigrations
python manage.py migrate
在管理器上调用过滤器方法会返回查询集
返回查询集的方法,称为过滤器,返回Queryset类型
写法:
# 下面两个写法相等
filter(键1=值1,键2=值2)
filter(键1=值1).filter(键2=值2)
返回单个值的方法
查询集返回列表,可以使用下标的方式进行限制,等同于sql中的limit和offset子句
注意:不支持负数索引
使用下标后返回一个新的查询集,不会立即执行查询
如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()引发DoesNotExist异常
#这会返回前5个对象 LIMIT 5
Entry.objects.all()[:5]
#这将返回第六个到第十个对象 OFFSET 5 LIMIT 5
Entry.objects.all()[5:10]
定义目版:layout.html
DOCTYPE html>
<html>
<head>
<title>{ % block title % }css{ % endblock % } 水果超市title>
head>
<body>
top--{{logo}}
<div>
{ % block content % }
内容
{ % endblock % }
div>
{ % block js % }
脚本
{ % endblock % }
body>
html>
继承母版:
{% extends 'layout.html' %}
{% block css %}
<link rel="stylesheet" href="{% static 'pluxxx.css' %}">
<style>
...
style>
{% endblock %}
{% block content %}
<h1>首页h1>
{% endblock %}
{% block js %}
<script src="{% static 'js/jqxxxin.js' %}">script>
{% endblock %}
Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中
Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数
属性:
count:对象总数
num_pages:页面总数
page_range:页码列表,从1开始,例如[1, 2, 3, 4]
方法:
page(num):下标以1开始,如果提供的页码不存在,抛出InvalidPage异常
异常exception
InvalidPage:当向page()传入一个无效的页码时抛出
PageNotAnInteger:当向page()传入一个不是整数的值时抛出
EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出Page对象
创建对象:
Paginator对象的page()方法返回Page对象,不需要手动构造
属性:
object_list:当前页上所有对象的列表
number:当前页的序号,从1开始
paginator:当前page对象相关的Paginator对象
方法:
has_next():如果有下一页返回True
has_previous():如果有上一页返回True
has_other_pages():如果有上一页或下一页返回True
next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
len():返回当前页面对象的个数
迭代页面对象:访问当前页面中的每个对象
我们原始方式理思路:开发不会采用(本质)【看了别人的学习视频自己也觉得非常麻烦】
Django组件
class UserInfo(models.Model):
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
depart = models.ForeignKey("Department", on_delete=models.CASCADE)
gender = models.SmallIntegerField(verbose_name="性别")
class MyForm(ModelForm):
xx = form.CharField*("...")
class Meta:
model = UserInfo
fields = ["name","password"]
def user_add(request):
if request.method == "GET":
form = MyForm()
return render(request, 'add.html',{"form":form})
<form method="post">
{% for field in form%}
{{ field }}
{% endfor %}
form>
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
form>
ModelForm可以帮助我们生成HTML标签。
class UserEditModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置
for name, field in self.fields.items():
# 字段中有属性,保留原来的属性,没有属性,才增加。
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
自定义类
class BootStrapModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段的插件设置
for name, field in self.fields.items():
# 字段中有属性,保留原来的属性,没有属性,才增加。
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
class UserEditModelForm(BootStrapModelForm):
class Meta:
model = models.UserInfo
fields = ["name", "password", "age",]
HTTP协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态,想了解更多就去百度
启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
session的语法:
get(key, default=None):根据键获取会话的值
clear():清除所有会话
flush():删除当前的会话数据并删除会话的Cookie
del request.session['member_id']:删除会话
中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出
激活:添加到Django配置文件中的MIDDLEWARE_CLASSES元组中
使用中间件,可以干扰整个处理过程,每次请求中都会执行中间件的这个方法
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse, redirect
class Auth(MiddlewareMixin):
def process_request(self, request):
# 排除那些不需要登录就能访问的页面
if request.path_info == "/login/":
return
# 排除超级管理系统登录
elif request.path_info.startswith("/admin/"):
return
# 如果登录就进入
info_dict = request.session.get("user")
if info_dict:
return
# 否则就跳到登录页面
return redirect("login")
应用中间件 setings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'myapp.middleware.auto.Auth'
]
在中间件的process_request方法
# 如果方法中没有返回值(返回None),继续向后走
# 如果有返回值 HttpResponse、render 、redirect,则不再继续向后执行。
#获取密码并md5
import hashlib
m = hashlib.md5()
m.update(bytes(request.POST['password'],encoding="utf8"))
print(m.hexdigest())