python_day18 Django表关系

day18 Django 表关系

ORM 1、类名------->表名
2、类属性----->字段类型
3、类对象----->表记录
数据库迁移:
python manage.py makemigrations
python 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.BigIntegerField

settings:
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 pymysql

app01->__init__.py:
import pymysql
pymysql.install_as_MySQLdb()

数据库迁移:
python manage.py makemigrations
python manage.py migrate

新建package:static
复制dist 引用bootstrap
settings最后加入一行:
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 

 

posted @ 2017-11-14 21:15  jing_1  阅读(230)  评论(0编辑  收藏  举报