Django之model

一.创建表

django中ORM和数据库的映射关系:

            表名  <-------> 类名

            字段  <-------> 属性

   表记录 <------->类实例对象

创建表就是一个创建类的过程:

class Book(models.Model):
    nid=models.AutoField(primary_key=True)
    title=models.CharField(max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=3)
    python manage.py makemigrations
    python manage.py migrate

 外键,一对一,多对多:

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()
 
    # 与AuthorDetail建立一对一的关系
    authorDetail=models.OneToOneField(to="AuthorDetail")
 
class AuthorDetail(models.Model):
 
    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)
#upload_to文件保存的位置  默认放在文件的根文件夹,如果加了media配置则media/下面
avatar=models.FileField(upload_to='avatars/',default='static/img/avatars/default.png'
# 与Publish建立一对多的关系,外键字段建立在多的一方 
#through是值定关联表
tags = models.ManyToManyField(
to="Tag",
through='Article2Tag',
through_fields=('article', 'tag'),
)

publish
=models.ForeignKey(to="Publish",to_field="nid") # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to='Author')
#联合唯一
class Meta:
unique_together = [
('article', 'user'),
]
'''
注意事项:  
1、id 字段是自动添加的
2、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
3、这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
4、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
5、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

'''

 都有哪些字段:

CharField    字符串
IntegerField   整型

字段属性:

max_length     最大长度 (CharField必须加)
choice=((1,''),(2,''))         相当于枚举

二.添加记录

#单表添加
#方式一:
publish_obj=Publish.objects.create(name="人民出版社",
    city="北京",email="renMin@163.com")
#方式二:
publish_obj=Publish(name="人民出版社",city="北京",email="renMin@163.com")
publish_obj.save()
#方式三:
Publish.objects.create(**request.POST.dict())
#带外键添加:
#一:
Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,       pagegeNum= 334,publish_id=1)
#二:
publish_obj=Publish.objects.get(nid=1)
Book.objects.create(title="金瓶眉",publishDate="2012-12-12", price=665,pageNum=334,publish=publish_obj)     
#多对多添加
book_obj=Book.objects.create(title="追风筝的人",publishDate="2012-11-12",price=69,pageNum=314,publish_id=1)
 
author_yuan=Author.objects.create(name="yuan",age=23,authorDetail_id=1)
author_egon=Author.objects.create(name="egon",age=32,authorDetail_id=2)
 
book_obj.authors.add(author_egon,author_yuan)    
'''将某个特定的 model 对象添加到被关联对象集合中。   =======    book_obj.authors.add(*[])
'''

#接触关系
book_obj.authors.remove()     # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear()       #清空被关联对象集合。

 批量添加数据:

book_list=[]
for i in range(500):
    book_obj=Book(title='book%s'%i,price=i)
    book_list.append(book_obj)
Book.objects.bulk_create(book_list)

三.查询记录

3.1 查询相关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

3.2 基于对象的跨表查询(子查询)

3.2.1 正向查询(按字段)

#一对多
# 查询nid=1的书籍的出版社所在的城市<br>
book_obj=Book.objects.get(nid=1)
print(book_obj.publish.city)
#一对一
author_egon=Author.objects.get(name="egon")
    print(author_egon.authorDetail.telephone)
#多对多
# 金瓶眉所有作者的名字以及手机号
 
    book_obj=Book.objects.filter(title="金瓶眉").first()
 
    authors=book_obj.authors.all()
 
    for author_obj in authors:
 
        print(author_obj.name,author_obj.authorDetail.telephone)

3.2.2 反向查询

#一对多
#表名小写+'_'+'set'

book_list=Publish.objects.filter(name='人民出版社').first().book_set.all()
print(book_list)
#一对一
#表名小写
#住在天堂的作者的名字
author_obj=AuthorDetail.objects.filter(addr='天堂').author
print(author_obj.name)
#多对多
#表名小写_set
# 查询egon出过的所有书籍的名字
book_objs=Author.objects.filter(name='egon').first().book_set.all()
for book_obj in book_objs:
   print(book_obj,book_obj.title)

 

3.3 基于双下划线的跨表查询(join查询)

注意:正向查询按字段,反向查询按表名

# 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)

    # 正向查询 按字段:publish

    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","price")

    # 反向查询 按表名:book

    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__price")



# 练习2: 查询egon出过的所有书籍的名字(多对多)

    # 正向查询 按字段:authors:
    queryResult=Book.objects
            .filter(authors__name="yuan")
            .values_list("title")

    # 反向查询 按表名:book
    queryResult=Author.objects
              .filter(name="yuan")
              .values_list("book__title","book__price")


# 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名


    # 正向查询
    queryResult=Book.objects
            .filter(publish__name="人民出版社")
            .values_list("title","authors__name")
    # 反向查询
    queryResult=Publish.objects
              .filter(name="人民出版社")
              .values_list("book__title","book__authors__age","book__authors__name")


# 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

    queryResult=Book.objects
            .filter(authors__authorDetail__telephone__regex="151")
            .values_list("title","publish__name"

3.4 聚合参数与分组查询

#聚会:aggregate(*args,**kwargs)
>>> Book.objects.all().aggregate(Avg('price'))
    {'price__avg': 34.35}
#aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
#可以向aggregate()子句中添加多个参数
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
#分组 annotate()

bookList=Book.objects.annotate(authorsNum=Count('authors'))
for book_obj in bookList:
    print(book_obj.title,book_obj.authorsNum)

3.5 F Q查询

F查询

Django 提供 F() 来对两个字段的值做比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 

# 查询评论数大于收藏数的书籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)

Q查询

可以利用& ,|,~三个符号进行与或非的逻辑运算

bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

四.修改和删除

修改:

update()

删除:

delete()

在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象

'''
delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用
'''
Entry.objects.all().delete()
#不想级联删除,可以设置为
pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

五. models的一些其他用法

http://www.cnblogs.com/hantaozi430/articles/8571378.html

原文地址:https://www.cnblogs.com/hantaozi430/p/8350526.html