python_day18 Django表关系

ぐ巨炮叔叔 提交于 2020-02-06 18:29:44
day18 Django 表关系ORM        1、类名------->表名        2、类属性----->字段类型        3、类对象----->表记录数据库迁移:python manage.py makemigrationspython manage.py migrate    流程:             url:  http://127.0.0.1:8070/index?     GET    无请求数据          # 添加          url:  http://127.0.0.1:8070/add        GET    无请求数据             url:  http://127.0.0.1:8070/add        post   请求数据             重定向:http://127.0.0.1:8070/index/  get    无请求数据          # 删除          http://127.0.0.1:8070/del/5   GET 无请求数据          重定向:http://127.0.0.1:8070/index/          #编辑          http://127.0.0.1:8070/edit/6  GET   无请求数据          http://127.0.0.1:8070/edit/6  POST   请求数据           重定向:http://127.0.0.1:8070/index/          注意点:              (1)请求方式对应不同的逻辑             (2) render方法执行过程             (3) 重定向单表操作 可以简写edit函数部分def edit(request):    models.Book.objects.filter(id=id).update(**request.POST.dict())方式2中的    **request.POST.dict()并不是万能的  单表,一对一表情况下可用    request和post需要一一对应起来今日内容    1、ORM表关系:一对多 多对多 一对一    2、ORM查询API:表与表关系    1、   确定是什么关系         if 一对多:            关联字段放在多的一方;           foreign key dep_id reference  dep(id)        if 多对多:              创建第三章表               create table student_teacher(                 id int primary key,               student_id int,               teacher_id int,               foreign key student_id reference  student(id)               foreign key teacher_id reference  teacher(id)            )        if 一对一:              foreign key ,关联字段可以放在两张表中任意一张            关联字段必须唯一约束ORM表关系:    1、配置:       DATABASES = {         'default': {            'ENGINE': 'django.db.backends.mysql',            'NAME': 's18day18',    #你的数据库名称            'USER': 'root',      #你的数据库用户名            'PASSWORD': '',      #你的数据库密码            'HOST': '',         #你的数据库主机,留空默认为localhost            'PORT': '3306',     #你的数据库端口         }      }2、 数据库引擎更改:       MYsqlDB---->pymysql      在应用的__init__文件中加入:         import pymysql         pymysql.install_as_MySQLdb()单表操作:       # 插入数据          # 插入数据方式1,create有返回值:插入的记录对象:            book_obj=models.Book.objects.create(title=title,pubDate=pubdate,price=price,publish=publish)            print(book_obj.title)            print(book_obj.price)          # 插入数据方式2:            book_obj=models.Book(title=title,pubDate=pubdate,publish=publish)            book_obj.price=price            book_obj.save()app01->models:class Book(models.Model):    id=models.AutoField(primary_key=True)    title=models.CharField(max_length=32)    pubDate=models.DateField()    price=models.DecimalField(max_digits=6,decimal_places=2)    publisher=models.ForeignKey(to=Publish)class Publish(models.Model):    name=models.CharField(max_length=32)    addr=models.CharField(max_length=32)    tel=models.BigIntegerFieldsettings:DATABASES = {    # 'default': {    #     'ENGINE': 'django.db.backends.sqlite3',    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),    # }    'default': {        'ENGINE': 'django.db.backends.mysql',        'NAME': "s18day18",        'USER': "root",        'PASSWORD': "mysql",        'HOST': '127.0.0.1',        'POST': '3306',    }}Terminal:pip3 install pymysqlapp01->__init__.py:import pymysqlpymysql.install_as_MySQLdb()数据库迁移:python manage.py makemigrationspython manage.py migrate新建package:static复制dist 引用bootstrapsettings最后加入一行:STATICFILES_DIRS=[    os.path.join(BASE_DIR,"static")]

以下内容基于上次项目基础上完成的。

urls:
views:
index.html:在上次页面基础上
{{ book_list.publisher.name }}    出版社名称即出现

一对多的添加:
urls:
views:
def index(request):
    if request.method == "POST":
        title=request.POST.get("title")
        .....
        publish_id=request.POST.get("publish_id")
        book_obj=models.Book.objects.create(title=title,...,publisher_id=publish_id) 使用字段添加表记录
        return redirect("/index/")
    publish_list=models.Publish.objects.all()
    return render(request,"add.html","publish_list":publish_list)
add.html:
<p>出版社<select name="publish" id="">
    {% for publish in publish_list %}
    <option value="{{ publish.id }}">{{ publish.name }}
    {% endfor %}    
添加页面中显示出版社名称,将出版社ID信息传送给前端页面

html页面form表单中 {{ csrf_token }}    setting中不必注释MIDDING第四行信息

单表插入数据方式2:
book_obj=models.Book(title=title,....,publisher_id=publish_id)
book_obj.save()        类实例化对象后save就可以增加表记录
一对多表插入数据方式2:
publish_obj=models.Publish.objects.filter(name="renmin")[0]
models.Book.objects.create(title=title,...,publisher=publish_obj)
#publisher 与这本书关联的出版社对象

create有返回值:插入的记录对象
模板templates之标签    if标签
urls:
views.temp:
temp.html:
<h3>TEMP
{% if n > 20 %}
<p>大于20
{% else %}    
<p>小于20
{% endif %}
obj=models.Book.objects.filter(id=1)[0]
<p>{{ obj.author.authordetail.name }}
={% with book_obj.publish.name="name" %}    with标签用法 使用name代指前面的那些
<p>{{ name }}
{% endwith %}

{% crsf_token %}    这个标签用于跨站请求爱伪站保护
<hr>
<form action="/temp/" method="post">
<p><input type="text" name="user">
<input type="submit">
{% crsf_token %}标示身份用的
for循环内 {% empty %} <p>没有响应书籍

自定义标签与过滤器的流程:
1、setting中INSTALLED_APPS检查是否有应用app01
2、在app01中templatetags包
3、templatetags创建任意.py文件
4、from django import template
from django.utils.safestring import make_safe
register=template.library()    #register的名字是固定的,不可改变
@register.filter    自定义标签
def multi(x,y):
    return x*y;
temp.html 将python函数与html模板结合起来了
5、{% load my_tag.py %}    <p>{{ a|multi:12 }}    即a*12

自定义过滤器与自定义标签的流程一模一样。
仅装饰器不同
@register.simple_tag
def multi_tag(x,y):
    return x*y;
{% load my_tag.py %} <p>{% multi_tag 3 5 %}    

自定义标签和自定义过滤器区别:
1、自定义标签只能接收到2个参数
2、自定义过滤器 可接受任意参数 不能与if等使用

html母版与继承
template下创建母版base.html
{% block content %}
{% endblock %}
new_index.html:
{% extends "base.html" %}
{% block content %}
扩展内容
{% endblock %}
追加内容 {{ block.super }}

查询相关API 13个方法 全部记住
urls:^query,qurry:
def query(request):
查询API
1 all()
book_list=models.Book.objects.all() #QuerySet [obj1,obj2...]
for book_obj in book_list:print(book_obj.title)
2 filter()  filter(**kwargs)
book_list=models.Book.objects.filter(price=123) #QuerySet [obj1,obj2...]
book_list=models.Book.objects.filter(price=123,title="数学书") 且
from django.db.models import Q
book_list=models.Book.objects.filter(Q(price=123)|Q(title="数学书")) 或
3 get方法 get(**kwargs)
a=models.Book.objects.get(title="数学书")#返回model对象book_obj,返回结果有且只有一个
print(a)
print(a.title)
get方法:数据库中没有或存在多个都会报错,只能有一个对象。一般用法是.get(id=1)
4 first() last()
book_obj=models.Book.objects.all().first()==[0] 返回对象
book_obj=models.Book.objects.filter(price=123).first()
5 exclude 筛选出不符合条件的QuerySet
book_obj=models.Book.objects.exclude(price=123)
6 count  QuerySet调用count()
book_obj=models.Book.objects.exclude(price=123).count()
7 order_by(*field)
book_obj=models.Book.objects.all().order_by("price") 从小到大
book_obj=models.Book.objects.all().order_by("-price") 从大到小
8 reverse 反向排序
book_obj=models.Book.objects.all().order_by("price").reverse() 从大到小
9 values QuerySet调用他们
book_obj=models.Book.objects.all().values("title") QuerySet[{},{},...]
book_obj=models.Book.objects.all().values("title","price")
10 values_list 
book_obj=models.Book.objects.all().values_list("title") [(),(),...]
11 exists
ret=models.Book.objects.all().exists()
if ret:print("OK")
else print("NO")

LOGINS的配置 加入setting中任意位置
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
只要执行models 都会打印出sql语句 日志Terminal
完美的双下划线 近似于模糊查询
book_obj=models.Book.objects.filter(id__gt=8) id大于8
book_obj=models.Book.objects.filter(title__startwith="语文")
 .filter(title__endwith="语文")
 .filter(title__icontains="语文") i不区分大小写 

查询相关API
<1> all():                 查询所有结果
 
<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象
 
<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                           如果符合筛选条件的对象超过一个或者没有都会抛出错误。
 
<5> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象
 
<4> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                           model的实例化对象,而是一个可迭代的字典序列
 
<9> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
 
<6> order_by(*field):      对查询结果排序
 
<7> reverse():             对查询结果反向排序
 
<8> distinct():            从返回结果中剔除重复纪录
 
<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
 
<11> first():              返回第一条记录
 
<12> last():               返回最后一条记录
 
<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

双下划线之单表查询
models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
 
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
 
models.Tb1.objects.filter(id__range=[1, 2])      # 范围bettwen and
 
startswith,istartswith, endswith, iendswith 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!