• Django-model基础


    Django-model基础

    在Django-ORM中表和类存在映射关系

           表名<------------>类名
    
           字段<------------>属性
    
         表记录<------------>类实例对象
    

    常用的字段选项

    每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数:

    (1)null
    如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
    
    (2)blank
    如果为True,该字段允许不填。默认为False。
    要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
    如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
    
    
    (3)default
    字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
    
    (4)primary_key
    如果为True,那么这个字段就是主键。如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True。
    
    (5)unique
    如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
    
    

    创建表单表操作

    创建表

    1.创建一张Book表用于存放指定的字段,在models.py模块中创建一个class用于创建表;

    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)
        publish=models.CharField(max_length=32)
    
    

    注释:

    AutoField     # 自增约束,自增前提这个键为数字类型
    CharField     # 表示字符串类型
    DateField     # 日期类型
    DecimalField  # 小数类型
    

    字段选项:

    primary_key=True                # 表示该字段为主键
    max_length=32                   # 表示字符串的长度
    max_digits=6,decimal_places=2   # 表示最大位数为 6位,小数点为2
    

    数据化迁移:

    写完表字段后,需要将创建的class类写入到数据库中,所以需要数据化迁移;

    # 在项目所在路径 依次执行
    C:pyDjangocmscms>python manage.py makemigrations
    
    C:pyDjangocmscms>python manage.py migrate
    

    注:如果执行完以上两步,发现没有完成表的创建,检查settings.py中是否注册该APP

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    ]
    

    表记录查询

    将数据引入到views.py模块中;

    from app01 import models
    

    通过objects表管理器操作单表中内容;

    1.查询出数据库中所有的数据--objects.all()

    from app01 import models
    def index(request):
        bookList=models.Book.objects.all()
        return render(request,"index.html",{"bookList":bookList})
    

    2.插入数据--create()

    from app01 import models
    def add(request):
        if request.method=="POST":
            # 如果前端为POST提交数据,先或去所有提交的数据内容
            title=request.POST.get("title")
            pubdate=request.POST.get("pubdate")
            price=request.POST.get("price")
            publish=request.POST.get("publish")
            
            # 插入数据 需要将,数据库字段:获取前端值, 一一对应
            models.Book.objects.create(title=title,pubDate=pubdate,price=price,publish=publish)
            
            # 添加完成数据后,将页面跳转到 首页
            return redirect("/index/")
    

    3.查询数据 和 删除数据,需要从前端接收指定的数据--filter(id=id)和delete()

    from app01 import models
    def delBook(request,id):
        # 根据id值查询出该条语句,然后进行删除
        models.Book.objects.filter(id=id).delete()
        return redirect("/index/")
    

    4.修改数据 -- update()

    def editBook(request,id):
        if request.method=="POST":
            title=request.POST.get("title")
            pubdate=request.POST.get("pubdate")
            price=request.POST.get("price")
            publish=request.POST.get("publish")
    
            # 根据id值查询出需要修改的那条语句,然后进行update()
            models.Book.objects.filter(id=id).update(title=title,pubDate=pubdate,price=price,publish=publish)
            return redirect("/index/")
    
        # 获取Book 对象,模板可以调用 所有的方法 edit_book.title  获取书名
        edit_book=models.Book.objects.filter(id=id)[0]      # 返回值QuerySet    [obj1,]
    
        # 当时get 获取时,给用户 返回 edit.html页面,并带着 edit_book 对象数据
        return render(request,"edit.html",{"edit_book":edit_book})
    

    表记录的添加

    普通字段添加

    方法一:通过save存入数据库

    publish_obj = models.Book(title=titles, pubDate=pubdate, price=price, publish=publish)
    publish_obj.save() # 将数据保存到数据库
    

    方法二:通过publish_obj存入数据库create

    models.Book.objects.create(title=titles,pubDate=pubdate,price=price,publish=publish)
    

    方法三:通过request.POST直接获取提交的内容,适用于单表操作 且 获取前端name值和表字段名需要匹配

    if request.method=="POST":
        models.Book.objects.create(**request.POST.dict())
        return redirect("/index/")
    

    一对多表外键字段

    方法一:根据obj对象赋值

    if request.method=="POST":
        titles = request.POST.get("title")
        pubdate = request.POST.get("pubdate")
        price = request.POST.get("price")
        publish_id = request.POST.get("pub")
        
        # 如果拿到的是一个出版社的名称,根据名称找出出版社的obj对象来赋值
        publish_obj=models.Publish.objects.filter(name="renmin")[0]
        
        # publisher:与这本书关联的出版社对象  ORM中publisher=Obj中publish_obj
        models.Book.objects.create(title=titles, pubDate=pubdate, price=price, publisher=publish_obj)  
    

    方法二:

    if request.method=="POST":
        titles = request.POST.get("title")
        pubdate = request.POST.get("pubdate")
        price = request.POST.get("price")
        publish_id = request.POST.get("pub")
        
        # 如果拿到的是一个关联id值,使用publisher_id直接赋值;
        book_obj=models.Book.objects.create(title=titles,price=price,pubDate=pubdate,publisher_id=publish_id)
        print(book_obj.title) 
    

    一对多的关联表创建

    在 一对多的关联表,进行创建关联关系时,需要把关联字段创建在内容多的那张表中;
    foreign key dep_id reference dep(id)

    ORM创建一对多表

    创建一对多的表,publisher为多表中的关联字段,指向Publish表中的主键

    from django.db import models
    # Create your models here.
    class Book(models.Model):
    
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=32)
        pubDate=models.DateField()
        price=models.DecimalField(max_digits=6,decimal_places=2)
    
        # 创建一个publisher 字段用作关联字段,Django会默认加上_id;关联到少的那张表 ForeignKey(to=表名) 无需指定主键
        publisher=models.ForeignKey(to="Publish")
    
    
    class Publish(models.Model):
        # Django会默认创建 一个主键id字段
        name=models.CharField(max_length=32)
        addr=models.CharField(max_length=32)
        tel=models.BigIntegerField()
    

    数据化迁移:

    # 在项目所在路径 依次执行
    C:pyDjangocmscms>python manage.py makemigrations
    
    C:pyDjangocmscms>python manage.py migrate
    

    通过objects表管理器操作一对多表中内容;

    1. 添加数据:

    def add(request):
        if request.method=="POST":
            titles=request.POST.get("title")
            pubdate=request.POST.get("pubdate")
            price=request.POST.get("price")
            
            # publish_id 获取前端传来的select 标签 name="pub" 
            publish_id = request.POST.get("pub")
            
            # 将数据写入到数据库中,publisher_id=publish_id  publisher_id为关联字段,publish_id为获取的前端name值
            # models.Book.objects.create(title=titles,pubDate=pubdate,price=price,publisher_id=publish_id)
            
            publish_obj = models.Book(title=titles, pubDate=pubdate, price=price,publisher_id=publish_id)
            publish_obj.save()
            
            return redirect(reverse('INDEX'))
            
        # 将所有 出版社的 信息传给前端模板
        Price_obj=models.Publish.objects.all()
        return render(request,"add.html",{"Price_obj":Price_obj})
    

    2. 前端页面操作:

    <form action="{% url 'ADD' %}" method="post">
        {% csrf_token %}
        <p>书名:<input type="text" name="title"></p>
        <p>出版日期:<input type="date" name="pubdate"></p>
        <p>价格:<input type="text" name="price"></p>
        <p>出版社:
            {# 在模板中使用select 标签,下拉框展示出版社名称供选择 #}
            <select name="pub" id="">
                {# 循环所有的出版社信息表 #}
                {% for foo in Price_obj %}
                    {# value值为出版社的id, 展示内容为  出版社名称 #}
                    <option value="{{ foo.id }}">{{ foo.name }}</option>
                {% endfor %}
            </select>
        </p>
        <input type="submit">
    </form>
    

    查询表记录

    Book表内容
    Book

    常用查询相关API

    1. 查询所有结果---all():

    def query(request):
        # 1 all()
        book_list=models.Book.objects.all()         # QuerySet  [obj1,obj2,]
        # 循环列出所有的 书名
        for book_obj in book_list:
            print(book_obj.title)
    

    输出:

    数学
    英语书
    物理书
    小黄书
    

    2. 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。---get():

    def query(request):
        # book_obj=models.Book.objects.get(price=134)
        book_obj=models.Book.objects.get(id=11)
        print(book_obj.title)
    

    输出:(如果符合筛选条件的对象超过一个或者没有都会抛出错误)

    英语书
    

    3. 它包含了与所给筛选条件相匹配的对象---filter():

    def query(request):
        # 获取所有价格 为 134 的书名
        book_list=models.Book.objects.filter(price=134)
    
        for book_obj in book_list:
            print(book_obj.title)
            
    ################################################
    def query(request):
        # 获取所有价格 为 134 的书名 且 书名为数学
        book_list=models.Book.objects.filter(price=134,title="数学")
    
        for book_obj in book_list:
            print(book_obj.title)
            
    ################################################
    from django.db.models import Q
    def query(request):
        # 查询出 价格为 134 且名字为 语文书
        book_list=models.Book.objects.filter(Q(price=134)|Q(title='语文书'))
        for book_obj in book_list:
            print(book_obj.title)
    

    输出:

    数学
    物理书
    ###############################################
    数学
    ###############################################
    数学
    物理书
    语文书
    

    4. 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列---values():

    def query(request):
        # 依照字典形式查询 出 指定的列
        ret=models.Book.objects.all().values("title",'price')  
        print(ret) 
        
    #################################################
    
    def query(request):
        # 依照字典形式查询 所有的 结果
        ret=models.Book.objects.all().values()  
        print(ret)  
    

    输出:

    <QuerySet 
    [{'title': '数学', 'price': Decimal('134.00')}, 
     {'title': '英语书', 'price': Decimal('34.00')}, 
     {'title': '物理书', 'price': Decimal('134.00')}, 
     {'title': '小黄书', 'price': Decimal('11.00')}]>
    
    #################################################
    
    <QuerySet [
    {'id': 10, 'title': '数学', 'pubDate': datetime.date(2017, 11, 7), 'price': Decimal('134.00'), 'publish': '北京'}, 
    {'id': 11, 'title': '英语书', 'pubDate': datetime.date(2017, 11, 7), 'price': Decimal('34.00'), 'publish': '机械'}, 
    {'id': 12, 'title': '物理书', 'pubDate': datetime.date(2017, 11, 9), 'price': Decimal('134.00'), 'publish': '人民出版社'}, 
    {'id': 13, 'title': '小黄书', 'pubDate': datetime.date(2017, 11, 17), 'price': Decimal('11.00'), 'publish': '小黄人出版社'}]>
    

    5. 它包含了与所给筛选条件不匹配的对象(取反not)价格不是134的---exclude():

    def query(request):
        book_list=models.Book.objects.exclude(price=134)  # QuerySet  [obj1,obj2,]
        for book in book_list:
            print(book.title)
    

    输出:

    英语书
    小黄书
    

    6. 对查询结果排序(正序:小到大)---order_by():

    def query(request):
        book_list = models.Book.objects.all().order_by("price").reverse()
        for i in book_list:
            print(i.title, i.price)
    

    输出:

    小黄书 11.00
    英语书 34.00
    数学 134.00
    物理书 134.00
    

    7. 对查询结果反向排序---reverse():

    def query(request):
        book_list = models.Book.objects.all().order_by("price").reverse()
        for i in book_list:
            print(i.title, i.price)
    

    输出:

    数学 134.00
    物理书 134.00
    英语书 34.00
    小黄书 11.00
    

    8. 从返回结果中剔除重复纪录---distinct():

    def query(request):
        # 将价格重复的项剔除
        ret=models.Book.objects.all().values("price").distinct() 
        print(ret)  
    

    输出:

    <QuerySet [{'price': Decimal('134.00')}, {'price': Decimal('34.00')}, {'price': Decimal('11.00')}]>
    

    9. values_list--它返回的是一个元组序列,values返回的是一个字典序列---values_list(*field):

    def query(request):
        # 依照元组形式查询 出 指定的列
        ret = models.Book.objects.all().values_list("title")
        print(ret) 
        
    ###########################################
    
    def query(request):
        # 依照元组形式查询 出 所有列
        ret = models.Book.objects.all().values_list()
        print(ret) 
    

    输出:

    <QuerySet [('数学',), ('英语书',), ('物理书',), ('小黄书',)]>
    
    ###########################################
    
    <QuerySet 
    [(10, '数学', datetime.date(2017, 11, 7), Decimal('134.00'), '北京'), 
     (11, '英语书', datetime.date(2017, 11, 7), Decimal('34.00'), '机械'), 
     (12, '物理书', datetime.date(2017, 11, 9), Decimal('134.00'), '人民出版社'), 
     (13, '小黄书', datetime.date(2017, 11, 17), Decimal('11.00'), '小黄人出版社')]>
    

    10. 返回数据库中匹配查询数量(count求匹配的条数)匹配价格为134的个数。---count():

    def query(request):
        count = models.Book.objects.filter(price=134).count()
        print(count)
    

    输出:

    2
    

    11. 返回第一条记录。---first():

    def query(request):
        book_obj=models.Book.objects.all().first()
        print(book_obj.title)
    

    输出:

    数学
    

    12. 返回最后一条记录。---last():

    def query(request):
        book_obj=models.Book.objects.all().last()
        print(book_obj.title)
    

    输出:

    小黄书
    

    13. 检查此次查询是否有结果,有结果就返回True,否则返回False。---exists():

    def query(request):
        ret=models.Book.objects.all().exists()
        if ret:
            print("Ok")
        else:
            print("NO")
    

    输出:

    Ok
    

    完美的__双下划线

    1.查询价格大于12的有几本书--"__gt=12":

    def query(request):
        book_list=models.Book.objects.filter(price__gt=10)
        print(book_list.count())
    

    输出:

    3
    

    2.查询依照 语文开头的书--'__startswith="语文"':

    def query(request):
        book_list=models.Book.objects.filter(title__startswith="语文")
        print(book_list[0].title)
    

    输出:

    语文书
    

    3.查询依照 书 结尾的书--'__endswith="书"':

        book_list=models.Book.objects.filter(title__endswith="书")
        for i in book_list:
            print(i.title)
    

    输出:

    语文书
    

    4.查询包含 书 字的书--'__contains="书"':

    def query(request):
        book_list=models.Book.objects.filter(title__contains="书")
        for i in book_list:
            print(i.title)
    

    输出:

    语文书
    数学书
    英语书
    物理书
    

    5.查询包含 不区分大小写 --'__icontains="书"':

    def query(request):
        book_list=models.Book.objects.filter(title__icontains="书")
        for i in book_list:
            print(i.title)
    

    输出:

    语文书
    数学书
    英语书
    物理书
    

    6.查询 价格大于12 小于120 的书 --'price__gt=12,price__lt=120':

    def query(request):
        book_list=models.Book.objects.filter(price__gt=12,price__lt=120)
        for i in book_list:
            print(i.title)
    

    输出:

    数学书
    物理书
    

    7.查询 价格 in [10,88,15]书 --'price__in=[10,88,15]':

    def query(request):
        book_list=models.Book.objects.filter(price__in=[10,88,15])
        for i in book_list:
            print(i.title)
    

    输出:

    数学书
    英语书
    物理书
    

    8.查询 价格 not in [10,88,15]书 --'exclude(price__in=[10,88,15])':

    def query(request):
        book_list=models.Book.objects.exclude(price__in=[10,88,15])
        for i in book_list:
            print(i.title)
    

    输出:

    语文书
    

    9.查询 价格 在[12,50]区间的书 --'filter(price__range=[12,50])':

    def query(request):
        book_list=models.Book.objects.filter(price__range=[12,50])
        for i in book_list:
            print(i.title)
    

    输出:

    语文书
    数学书
    

    一对多的查询

    正向查询

    1.根据外键所在的表,进行查询设定为正向查找

    def temp(request):
        # 查询出书名为小黄书的,出版社名称
        book_obj=models.Book.objects.filter(title="小黄书")[0].publisher.name
        print(book_obj)
    

    输出:

    小黄人出版社
    

    反向查找book_set

    1.根据出版社,查询出《小黄人出版社》出版的所有书籍

    def temp(request):
        # 查询出 名称为小黄人出版社的 对象,根据book_set 查出结果
        pub_obj=models.Publish.objects.filter(name="小黄人出版社")[0].book_set.values_list("title","price")
        print(pub_obj)
    

    输出:

    <QuerySet [('小黄书', Decimal('11.00')), ('小兵张嘎', Decimal('17.00'))]>
    

    反向查找之双下划线__形式

    正向查询按字段,反向查询按表名

    1.根据出版社,查询出《小黄人出版社》出版的所有书籍

    def temp(request):
        # publisher__name  是Book表   外键字段的名称__name
        book_ret = models.Book.objects.filter(publisher__name="小黄人出版社").values_list("title","price")
        print(book_ret)
    

    输出:

    <QuerySet [('小黄书', Decimal('11.00')), ('小兵张嘎', Decimal('17.00'))]>
    

    ###多对多表关系 多对多关联表的创建,依照第三张表的创建关联关系; ####创建多对多关系表 ManyToManyField("表名") 1.创建多对多的表关系 ManyToManyField ```python from django.db import models

    书籍表

    class Book(models.Model):
    title=models.CharField(max_length=32)
    pubDate=models.DateField()
    price=models.DecimalField(max_digits=6,decimal_places=2)
    read_num=models.IntegerField(default=0)
    comment_num=models.IntegerField(default=0)

    # 创建一个publisher 字段用作关联字段,Django会默认加上_id;关联到少的那张表 ForeignKey(to=表名) 无需指定主键
    publisher=models.ForeignKey(to="Publish")
    
    # ManyToMany 指定于哪张表进行多对多的关系,默认会创建一个第三张表,用于绑定多对多的关系记录
    # 于 to="Author" 指定多对多的关系
    authors = models.ManyToManyField(to="Author")
    

    出版社表

    class Publish(models.Model):
    # Django会默认创建 一个主键id字段
    name=models.CharField(max_length=32)
    addr=models.CharField(max_length=32)
    tel=models.BigIntegerField()

    作者表

    class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    <b>数据化迁移:</b>
    ```python
    # 在项目所在路径 依次执行
    C:pyDjangocmscms>python manage.py makemigrations
    
    C:pyDjangocmscms>python manage.py migrate
    

    多对多关系添加(绑定)

    1.添加新书籍,将所有作者绑定到该书上;

    def add(request):
        if request.method == "POST":
            title = request.POST.get("title")
            price = request.POST.get("price")
            pubdate = request.POST.get("pubdate")
            pub = request.POST.get("pub")
            # 获取添加这么书的对象
            book_obj=models.Book.objects.create(title=title, price=price, pubDate=pubdate, publisher_id=pub)
    
            # 获取 作者 的QuerySet集合
            auth_list=models.Author.objects.all()
    
            # 多对多的关系绑定,将这个列表集合,通过*args 的方式add 给book_obj 对象的 authors关联表
            book_obj.authors.add(*auth_list)
    
            return HttpResponse("OK")
    

    多对多关系删除(解除绑定)

    1.将指定的作者与书籍绑定关系取消--remove;

    def add(request):
        if request.method == "POST":
            # 接触绑定关系
            # 找出要解除绑定关系的那本书对象
            book_obj=models.Book.objects.get(id=318)
            
            # 找出要解除绑定关系的用户对象
            wangwu=models.Author.objects.get(name="王五")
            
            # 通过book_obj对象的authors关联关系,remove出 wangwu对象
            book_obj.authors.remove(wangwu)
            return HttpResponse("OK")
    

    2.清空指定书籍对象的作者--clear;

    def add(request):
        if request.method == "POST":
            # 接触绑定关系
            # 找出要解除绑定关系的那本书对象
            book_obj=models.Book.objects.get(id=317)
    
            book_obj.authors.clear()
            return HttpResponse("OK")
    

    多对多关系查询

    1.查询出id为318这本书的所有作者名称和年龄;

    def add(request):
        if request.method == "POST":
            
            # 查出318这边书的对象
            book_obj=models.Book.objects.filter(id=318)[0]
            
            # 根据这本书对象.authors.values_list取出作者QuerySet集合
            age=book_obj.authors.values_list("name","age")
            print(age)
    
            return HttpResponse("OK")
    

    一对一表关系

    一对一关联表创建,关联关系在任意一张表中,对应关系只能是一对一,关联字段添加一个(unique)属性
    在foreign key 的基础上,关联字段必须唯一约束

    创建一对一关系表 OneToOneField("表名")

    1.创建一对一的表关系 OneToOneField

    from django.db import models
    
    # 作者表
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
    
    # 作者详情表
    class AuthorDetail(models.Model):
        addr=models.CharField(max_length=64)
    
        # 创建关联关系表,一对一的关系,可以任意创建在一张表中
        author=models.OneToOneField("Author")
    

    数据化迁移:

    # 在项目所在路径 依次执行
    C:pyDjangocmscms>python manage.py makemigrations
    
    C:pyDjangocmscms>python manage.py migrate
    

    一对一关系表正向查询

    1.查询家在甘家口的作者名称

    def temp(request):
        authordetail=models.AuthorDetail.objects.filter(addr="甘家口")[0]
        print(authordetail.author.name)
        return HttpResponse("OK")
    

    输出:

    王五
    

    一对一关系表反向查询

    1.查询出李四住在哪里;

    def temp(request):
        # 因为是一对一的关系,所以查询出来的结果一定是唯一的对象,所以不需要 _set的参数;
        att=models.Author.objects.filter(name="李四")[0].authordetail.addr
        print(att)
        return HttpResponse("OK")
    

    输出:

    回龙观
    
  • 相关阅读:
    chrome 等浏览器不支持本地ajax请求的问题
    3:1 类型转换
    WebService-WSDL简单介绍
    WebService—CXF整合Spring实现接口发布和调用过程
    WebService—CXF—实现接口发布和客户端调用
    WebService—规范介绍和几种实现WebService的框架介绍
    (转)c# 扩展方法
    (转)C# Textbox的ImeMode取值对中文输入法的影响
    (转)Nandflash读写
    (转+整理)Nandflash存储
  • 原文地址:https://www.cnblogs.com/baolin2200/p/7828827.html
Copyright © 2020-2023  润新知