zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    配置 jvisualvm 监控Java虚拟机
    配置 IDEA 远程连接应用服务器
    Java虚拟机知识点【工具】
    Java虚拟机知识点【参数】
    Java虚拟机知识点【GC】
    Java虚拟机知识点【方法调用】
    Java虚拟机知识点【字节码】
    [NOIP2017]逛公园 题解
    [CSP-S模拟测试72]题解
    [CSP-S模拟测试69]题解
  • 原文地址:https://www.cnblogs.com/liweijing/p/7834701.html
Copyright © 2011-2022 走看看