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")

输出:

回龙观
原文地址:https://www.cnblogs.com/baolin2200/p/7828827.html