django基础

django基础

django orm表关系创建

多表创建的三种形式

一对多
多对多
一对一

以图书管理管理系统为例可分为几种表

图书表

图书和出版社是一对多的外键关系,一对多外键关系,外键字段建在多的一方。

出版社

出版社和图书表是一对多的外键关系

作者表

图书与作者是多对多外键关系
多对多外键关系 外键字段无论建在哪张表里面都可以
但是推荐你建在查询频率较高的那种表中
			
作者与作者详情是一对一的外键关系
一对一外键关系 外键字段建在哪张表里面都可以
但是推荐你建在查询频率较高的那种表中

方便我们后面的基于orm查询

注意:

ForeignKey字段以及OneToOneField字段 在创建表的时候orm都会自动给该字段加_id的后缀,无论自己有没有加,都默认给你加上。

在书写表关系时,要先把基于表全部写出来之后再考虑外键字段

代码:

from django.db import models

	# Create your models here.
class Book(models.Model):
	# id是自动创建的 我们就不写了
	title = models.CharField(max_length=64)
	# price为小数字段 总共8位小数位占2位
	price = models.DecimalField(max_digits=8,decimal_places=2)

	# 书籍与出版社 是一对多外键关系
	publish = models.ForeignKey(to='Publish')  # 默认关联字段就是出版社表的主键字段
	# publish = models.ForeignKey(to=Publish)  # to后面也可以直接写表的变量名 但是需要保证该变量名在当前位置的上方出现

	# 书籍与作者   是多对多外键关系
	authors = models.ManyToManyField(to='Author')  # 书籍和作者是多对多关系
	"""
	authors字段是一个虚拟字段 不会真正的在表中创建出来
	只是用来告诉django orm 需要创建书籍和作者的第三张关系表
	"""

class Publish(models.Model):
	name = models.CharField(max_length=64)
	addr = models.CharField(max_length=64)


class Author(models.Model):
	name = models.CharField(max_length=32)
	phone = models.BigIntegerField()
	# 一对一外键关系建立
	author_detail = models.OneToOneField(to='AuthorDetail')


class AuthorDetail(models.Model):
	age = models.IntegerField()
	addr = models.CharField(max_length=255)

django 请求生命周期流程图

django 请求生命周期的流程图:

路由层

路由匹配

urlpatterns = [
		url(r'^admin/', admin.site.urls),
		url(r'test',views.test),
		url(r'testadd',views.testadd)
	]
url方法第一个参数是一个正则表达式
路由匹配按照正则匹配 一旦正则能够匹配到内容 会立刻执行对应的视图函数
不会再继续匹配了

正则表达式
是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,大多用于爬虫。

首先,python中的正则表达式大致分为以下几部分:
元字符
模式
函数
re 内置对象用法
分组用法
环视用法
所有关于正则表达式的操作都使用 python 标准库中的 re 模块。
用户输入url不加最后的斜杠 django会默认自动加上    
你可以在配置文件中指定是否开启该功能
APPEND_SLASH = True/False

分组就是给一段正则表达式加括号

无名分组

分组就是给一段正则表达式加括号

在路由匹配的时候给某段正则表达式加了括号
匹配的时候会将括号内正则表达式匹配到的内容当做位置参数传递给对应的视图函数
# 无名分组
url(r'^test/([0-9]{4})/',views.test)
# 视图函数
def index(request,args):
	return HttpResponse('')

有名分组

给一段正则表达式起一个别名
匹配的时候会将括号内正则表达式匹配到的内容当做关键字参数传递给对应的视图函数
# 有名分组
url(r'^test/(?P<year>d+)/',views.test)
# 视图函数
def index(request,year):
    ....

补充:

# 无名有名能否混合使用   >>>    不能!!!
# url(r'^test/(d+)/(?P<year>d+)/', views.test),
# 虽然不能混合使用 但是同一种命名方式 可以使用多个
# url(r'^test/(d+)/(d+)/',views.test),
url(r'^test/(?P<xxx>d+)/(?P<year>d+)/',views.test),

反向解析

通过一些方法 能够得到一个结果  该结果可以访问到对应的url
		
使用方式 
	先给路由与视图函数对应关系 起一个名字
		url(r'^testadd/',views.testadd,name='add')
	前端解析
		{% url 'add' %}
	后端解析
		from django.shortcuts import render,HttpResponse,redirect,reverse
		reverse('add')

无名分组反向解析

# 无名分组反向解析
	url(r'^testadd/(d+)/',views.testadd,name='add')
		前端解析
			{% url 'add' 1 %}
		后端解析
			reverse('add',args=(12,))

有名分组反向解析

# 有名分组反向解析
	url(r'^testadd/(?P<year>d+)/',views.testadd,name='add')
前端解析
	{% url 'add' 1 %}  # 推荐使用
	{% url 'add' year= 1 %}  # 标准的
后端解析
	reverse('add',args=(12,))
	reverse('add',kwargs={'year':12})

伪代码诠释:

"""
url(r'^edit_user/(d+)/',views.edit_user,names='edit')
		
		
{% for user_obj in user_queryset %}
	<a href="edit_user/{{ user_obj.id }}/">编辑</a>
	<a href="{% url 'edit' user_obj.id %}">编辑</a>
{% endfor %}
		
		
def edit_user(request,edit_id):
	reverse('edit',args=(edit_id,))
    
"""

路由分发

当django项目比较庞大的时候 路由与视图函数对应关系较多
总路由代码太多冗长
考虑到总路由代码不好维护 django支持每个app都可以有自己的urls.py
并且总路由不再做路由与视图函数的对应关系 而仅仅只做一个分发任务的操作
		
根据请求的不同 识别出当前请求需要访问的功能属于哪个app然后自动
下发到对应app里面的urls.py中 然后由app里面的urls.py做路由与视图函数的匹配
		
不仅如此每个app除了可以有自己的urls.py之外 还可以有自己的static文件夹 templates模板文件
基于上面的特点 基于django分小组开发 会变得额外的简单
每个人只需要开发自己的app即可 之后只需要创建一个空的django项目
将多个人的app全部拷贝项目下 配置文件注册
总路由分发一次 

需要一个分发的模块

1.总路由

from django.conf.urls import url,include
# 路由分发  注意事项应用名后面千万不能加$
		# from app01 import urls as app01_urls
		# from app02 import urls as app02_urls
		# url(r'^app01/',include(app01_urls)),
		# url(r'^app02/',include(app02_urls))
		
		# 简写
		url(r'^app01/',include('app01.urls')),
		url(r'^app02/',include('app02.urls'))

2.子路由

from django.conf.urls import url
from app01 import views

urlpatterns = [
	url(r'^index/',views.index)
	]
			
from django.conf.urls import url
from app02 import views

urlpatterns = [
	url(r'^index/',views.index)
	]

名称空间(了解)

url(r'^app01/',include('app01.urls',namespace='app01'))
url(r'^app02/',include('app02.urls',namespace='app02'))
后端解析
reverse('app01:index')
reverse('app02:index')
前端解析
{% url 'app01:index' %}
{% url 'app02:index' %}
# 在给路由与视图函数起别名的时候只需要保证永远不出现冲突的情况即可
# 通常情况下我们推荐期别名的时候加上当前应用的应用名前缀
		
url(r'^index/',views.index,name='app01_index')
url(r'^index/',views.index,name='app02_index')

虚拟环境

我们想做到针对不同的项目 ,只安装项目所需要的功能模板
项目用不到的一概不装,来避免加载资源时的消耗。

如何创建虚拟环境

虚拟环境就类似于一个纯净的python解释器,通俗的讲,没有创建一个虚拟幻境就类似于你重新下载一个python解释器

建议:

虚拟环境不推荐你使用太多
对于学习阶段我们还是用本机的环境即可,将所有模块全部装到本机环境下

django版本区别

路由层

1.x 用的是url
2.x、3.x用的是path
url第一个参数是一个正则表达式

而path第一个参数不支持正则表达式 默认写什么就是什么

如果你觉得path不好用2.x、3.x 给你提供一个跟你url一样的功能
re_path 等价于1.x版本里面的url功能

path的方法功能

虽然path不支持正则表达式 但是它给你提供了五种默认的转换器
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
path('login/<int:year>/',login)

除了默认的五种转换器之外 还支持你自己定义的转换器

class MonthConverter:
regex='d{2}' # 属性名必须为regex

def to_python(self, value):
	return int(value)

def to_url(self, value):
	return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
	

正则表达式的回顾

正则表达式
是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,大多用于爬虫。

首先,python中的正则表达式大致分为以下几部分:
元字符
模式
函数
re 内置对象用法
分组用法
环视用法
所有关于正则表达式的操作都使用 python 标准库中的 re 模块。

伪静态

url以 .html结尾 给人的感觉好像这个文件是被写死的,内容不会轻易改变伪静态。

注意:

为了提高你的网站被搜索引擎收藏的力度,提供网站的SEO查询效率,但是无论怎么做优化,都是抗不过RMB玩家的

视图层

### 	三把斧
from django.shortcuts import  HttpResponse render redirect
HttpResponse ('字符串')
	返回字符串
render
	返回html页面  并且可以给html页面传数据
	模板的渲染(将数据在后端按照模板语法放入html对应的位置)
			
redirect
重定向(原本想访问A但是内部自动给你转到了B上面)

代码:

def index(request):  返回一个字符串
		return HttpResponse('你好啊 小妹妹')


def login(request):
	return render(request,'login.html',{'user_dict':{'username':'jason','password':123},'userxxx':'hello world'})


def home(request):
		# return redirect('https://www.mzitu.com')
	return redirect('/index')    /index可以是别人网站的全路径,可是自己写的全路径。

JsonResponse

from django.http import JsonResponse
def xxx(request):
	user_dict = {'username':'jason好帅哦 我好喜欢!','password':'123'}
	# json_str = json.dumps(user_dict,ensure_ascii=False)
	# return HttpResponse(json_str)
	l = [1,2,3,4,5,6,7,8,9,]
	# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
	return JsonResponse(l,safe=False)  # 序列化非字典格式数据 需要将safe改为False
前后端数据交互

form 表单上传文件 后端如何获取

1.action
action的使用:1.不写 默认朝当前地址提交数据  2.全路径    3.后缀(/index)

2.method   post
提交post请求的时候 需要先去配置文件中注释掉一行			
3.enctype  formdata

原文地址:https://www.cnblogs.com/WQ577098649/p/12158041.html