Django问题回顾

Django回顾

1.创建项目及配置

(1) pycharm创建项目
	最好是新建的时候创建 应用,省的自己创建的时候再去手动配置 
	-->settings.py下的  INSTALLED_APPS  和  TEMPLATES (新增了templates文件夹的路径)
	
(2) 配置
	1> django连接数据库 
		settings.py 中改 DATABASES
		在 应用 或者 项目 下的__init__.py中配置
		
	2> 操作数据库
    	models.py文件 --> ORM
    	数据库迁移命令 --> 将类真正映射到数据库的表
    		python manage.py makemigrations  --> 在migration文件夹下新建了个文件
    		python manage.py migrate  --> 真正操作了数据库
    	ps: 当修改已经创建的表的时候,尤其是新建字段,得设置默认值,或者设置 null=True
    	
    3> 新建应用
    	去settings.py文件中的 INSTALLED_APPS 配置
    	
    4> 配置静态文件
    	settings.py文件中 最下方加上 STATICFILES_DIRS 配上路径

具体内容看博客就行:https://www.cnblogs.com/xt12321/p/10999471.html

2.路由控制

2.1 版本问题

	django 1.0 
		from django.conf.urls import url
		urlpatterns = [
        	url(正则表达式, views视图函数,参数,别名),
    	]
    	
	django 2.0 
		from django.urls import path,re_path
		 urlpatterns = [
		  	 re_path(r'^app01/',include('app01.urls')), # 相当于1.0版本中的urls,语法一样 
             path('index/', views.index), # 第一个参数是要完全匹配,不是正则表达式
         ]

2.2 反向解析

urls.py文件:
	urlpatterns = [
        # 给url匹配模式起名为app01_index
        url(r'^index/(\d*)', views.index, name='app01_index'), 
	]
解释:app01_index是正则表达式识别的内容为 /index/(任意数字都可以识别)

views.py文件中:
from django.urls import reverse
def index(request, ar):   # 1231
    url = reverse('app01_index', args=(ar,))   # /index/1231
    return render(request, 'login.html', locals())
    
解释:类似于join方法,将字段进行拼接

login.html文件中:
<body>
    <p>{% url 'app01_index' ar %}</p>
</body>

url:http://127.0.0.1:8000/index/1231
界面显示:/index/1231

2.3 名称空间

为了解决反向解析时,出现定义的URL的name重复的问题
---> 也可以加上app的名称,这样就不会冲突

详细内容见博客:https://www.cnblogs.com/xt12321/p/11000532.html

3.视图层

针对的就是views.py文件
分为FBV和CBV两种,FBV是基于函数的view,CBV是基于类的view

3.1 CBV示例:

CBV:
# 路由层代码
from app01 import views
urlpatterns = [
    # url(r'^mycls/',views.view)
    url(r'^mycls/',views.MyLogin.as_view())
]

# 视图层代码
from django.views import View
from django.shortcuts import HttpResponse
class MyLogin(View):
    def get(self,request):
        return HttpResponse('get')
    
    def post(self,request):
        return HttpResponse('post')

3.2 request的方法

request.method:表示提交请求使用的HTTP方法。它总是大写的。
request.GET:一个类字典对象,包含所有的HTTP的GET参数的信息。
request.POST:一个类字典对象,包含所有的HTTP的POST参数的信息。
request.FILES:一个类字典对象,包含所有上传的文件。
request.path:一个字符串,表示请求的路径(不含域名)。
request.get_full_path():一个字符串,表示请求的完整路径。
request.body:一个字符串,代表请求报文的主体。

详细内容见博客:https://www.cnblogs.com/xt12321/p/11004741.html

4.模板层

4.1 数据传递

后端:
# 第一种 return render(request,'index.html',{'n':n})
# 第二种 return render(request,'index.html',locals())  

4.2 过滤器

过滤器的语法: {{ value|filter_name:参数 }}
支持链式操作、接受传参、参数有空格需要引号括起来、|左右不准空格
ps:Django的模板语言中提供了大约六十个内置过滤器。

自定义filter:
    自定义过滤器只是带有一个或两个参数的Python函数:
        变量(输入)的值 - -不一定是一个字符串
        参数的值 - 这可以有一个默认值,或完全省略
    例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数“bar”。

4.3 标签

for循环、if判断、嵌套使用、自定义过滤器、自定义inclusion_tag

for循环: forloop:这个里面的东西很多
自定义过滤器:
    必须做的三件事:
        1.在应用名下新建一个名为templatetags文件夹(必须叫这个名字)
        2.在该新建的文件夹内新建一个任意名称的py文件
        3.在该py文件中需要固定写下面两句代码
        
        from django import template
        register = template.Library()
        
        使用之前请先导入  --> 在html模板页面中导入
        {% load my_filter %}
        这个my_filter是自定义的py文件名(上面定义的三个步骤其二)

        # 自定义过滤器
            @register.filter(name='XBB')
            def index(a,b):
                return a+b

4.4 模板的继承与导入

1.继承	
    1.在被继承的模板中划分区域 {% block 给区域起的名字 %} {% endblock %}
    2.在要继承的模板中导入 	
        2.1 先继承所有内容{% extends 'home.html' %}
        2.2 修改指定位置内容 {% block content %} {% 指定内容 %}
  
 2.导入
 	将一段html当做模块的方式导入到另一个html展示 {% include '想导入的html文件名' %}

具体的见博客:https://www.cnblogs.com/xt12321/p/11006137.html

5.Django ORM

5.1 Django使用MySQL

 在settings.py中配置:
    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day58',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '123456',
        }
    }
    在应用下或者项目下的__init__.py文件中配置:
        import pymysql
        pymysql.install_as_MySQLdb()

5.2 数据库迁移命令

# 将models里设计的表迁移到MySQL数据库中:
python manage.py makemigrations
python manage.py migrate

5.3 tests.py 测试文件

# 在应用下的tests.py文件中写测试文件,必须先进行下面的操作
from django.test import TestCase
import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day58.settings")
    import django
    django.setup()

5.4 基于对象或queryset操作数据

0.增数据(单独):
	user_obj = models.User.objects.create(字段名='值')
1.基于对象:
	例子:
	user_obj = models.User.objects.filter(name='lisi').first()
	user_obj.age = 18
	user_obj.save()
	# 优点:像使用对象一样去操作数据库数据
	# 缺点:save是该条记录的所有数据重新存了一遍
	
2.基于queryset:
	例子:
	 models.User.objects.filter(name='kevin').update(age=66)

5.5 查询数据

查询方法及分类:
1>返回QuerySet对象的方法有:

	(1) all():                  查询所有结果
	(2) filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
	(3) exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
    (4) order_by(*field):       对查询结果排序('-id')
    (5) reverse():              对查询结果反向排序
    (6) distinct():            从返回结果中剔除重复纪录,查询的记录必须有完全一样的(一般按字段查询之后会有)
	
2>特殊的QuerySet
    (1) values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model 的实例化对象,而是一个可迭代的字典序列
	(2) values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
    
3>返回具体对象的
	(1) get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
	(1) first():                返回第一条记录
	(2) last():                返回最后一条记录
	
4>返回布尔值的方法有:
	(1) exists():              如果QuerySet包含数据,就返回True,否则返回False

5>返回数字的方法有
	(2) count():                返回数据库中匹配查询(QuerySet)的对象数量。

5.6 要记下来的一点

跨表修改表中数据:
	修改书籍与作者的关系  set()  set传的必须是可迭代对象!!!
    book_obj = models.Book.objects.filter(pk=3).first()
    可以传数字和对象,并且支持传多个
    修改:
        # 传数字
        book_obj.authors.set((1,))
        book_obj.authors.set((1,2,3))

        # 对象
        author_list = models.Author.objects.all()
        book_obj.authors.set(author_list)
    清除:
    	book_obj.authors.remove(1)
    

5.7 基于双下划线、对象查询

1.基于对象查询
	正向查询:从外键在本表开始查询,跨表查询数据
	反向查询:从外键不在本表开始查询对应关系表的数据
例子:
	正向查询:
		查询书籍是三国演义的出版社邮箱
        book_obj = models.Book.objects.filter(title='三国演义').first()
        结果:123.qq.com
    反向查询:
        查询出版社是南方出版社出版的书籍       一对多字段的反向查询
        # 首先要确定的是,书籍与南方出版社是有关系的,但是外键在书籍那边,
        # 从出版社开始查询数据,先得到出版社对象,在使用固定语法跨表到book表中,最后拿到数据。
        publish_obj = models.Publish.objects.filter(name='南方出版社').first()
        print(publish_obj.book_set)  # app01.Book.None
        print(publish_obj.book_set.all())
2.基于双下划线的查询
	正向查询:
		查询书籍为三国演义的出版社地址
    	res = models.Book.objects.filter(title='三国演义').values('publish__addr','title')
	反向查询:
		查询南方出版社出版的书名
    	res = models.Publish.objects.filter(name='南方出版社').values('book__title')

5.8 聚合查询 aggregate

1.需要先导包
from django.db.models import Max,Min,Count,Sum,Avg

2.例子
(1)查询所有书籍的作者个数
    res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors'))

5.9 分组查询 annotate

1.例子
(1)统计每个出版社出版的书的平均价格
    res = models.Publish.objects.annotate(
        avg_price=Avg('book__price')).values('name','avg_price')

(2)统计每一本书的作者个数
    res = models.Book.objects.annotate(
        count_num=Count('authors')).values('title','count_num')

6.F、Q查询

6.1 F查询

当想让两个字段进行比较的时候,就需要Django的F()来实现。
(1)先导入F、Q
     from django.db.models import F,Q
    
(2)查询卖出数大于库存数的商品
    res = models.Product.objects.filter(maichu__gt=F('kucun'))
    # <QuerySet [<Product: 商品对象的名字:华为保时捷>, <Product: 商品对象的名字:索尼A6000>]>
(3)其他操作
	models.Product.objects.update(price=F('price')+100)
	
	from django.db.models.functions import Concat
    from django.db.models import Value
    models.Product.objects.update(name=Concat(F('name'), Value('特供')))

6.2 Q查询

(2)res = models.Product.objects.filter(Q(price=103), Q(name='橡皮特供'))  # and
    # <QuerySet []>

(3)res = models.Product.objects.filter(Q(price=103) | Q(name='橡皮特供'))  # or
    # <QuerySet [<Product: 商品对象的名字:橡皮特供>, <Product: 商品对象的名字:铅笔特供>]>

(4)二者混合使用   需要注意的是Q对象必须放在普通的过滤条件前面
    res = models.Product.objects.filter(~Q(name='橡皮特供'), price=103)
    # <QuerySet [<Product: 商品对象的名字:铅笔特供>]>   非橡皮特供,且价格为103的商品

6.3 only和defer

only和defer,查询拿到的都是对象,但是两者是相反的

详情链接:https://www.cnblogs.com/xt12321/p/11018789.html

7、前后端数据传输、Ajax、分页器

链接:https://www.cnblogs.com/xt12321/p/11024417.html

posted @ 2019-06-17 08:11  xt12321  阅读(166)  评论(0编辑  收藏  举报