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 

  • 相关阅读:
    宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/liweijing/p/7834701.html
Copyright © 2011-2022 走看看