数据库基本操作

查询

1、values & values_list

# 查询数据表PhoneDep中 name 列的所有信息;distinct 用于去重; __用于联表查询;
PhoneDep.objects.all().values_list('name') # 返回 元组列表 
>><QuerySet [('ODM',),('手机专项测试室',),('项目经理',)]>

PhoneDep.objects.all().values_list('name',flat=True) # 加入flat=True后,返回 值列表;当有多个列时,不能使用此参数了
>><QuerySet ['ODM', '手机专项测试室', '项目经理']>

PhoneDep.objects.all().values('name') # 返回 字典列表 
>><QuerySet [{'name': 'ODM'}, {'name': '手机专项测试室'},{'name': '项目经理'}]>

2、get

# 通过get获取 不存在时报错、有多个时也报错;
Phone.objects.get(id=1)
Phone.objects.get(user='tom')

3、filter

  1. 包含 __contains=
    Blog.objects.filter(title__contains="django"); 前面加i时不区分大小写

4、F查询

同一经表格的不同字段之间的查询

# 所有书的价格上涨10
Book.objects.all().update(price=F('price')+10)

5、Q查询

Q表达式代表了Where子句的一个条件,可以用于多个where条件的连接。

# 默认的,为与的关系;| 为或的关系
from django.db.models import Q
News.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

7、annotate

valus_list:相当于按它分组,后面的参数都是按其分组后的数据,可以用于统计,方便使用

phone_spread = Phone.objects.filter(Q(name=my_charge), Q(stage__contains=phone_stage)).values_list(
    'phone_dep').annotate(nums=Count('phone_dep'),
                          nums_in=Sum(Case(When(can_borrow='借出', then=1), default=0),
                                      output_field=IntegerField())
                          )

# 方式1:
Phone.objects.create(user='tom',password='jerry')
# 方式2:
obj = Phone(user='tom',password='jerry')
obj.save()
# 方式3:
dic = {'user':'tom','password':'jerry'}
Phone.objects.create(**dic)

# 批量增数据
product_list_to_insert = list()
for x in range(10):
  product_list_to_insert.append(Product(name='hisense',price=12))
Product.objects.bulk_create(product_list_to_insert)

Phone.objects.filter(user__contains='tom').delete()

# 方式1:批量改
Phone.objects.filter(user__contains='tom').update(password='jerry')
# 方式2:
obj = Phone.objects.get(user='tom')
obj.password = 'jerry'
obj.save()

小知识

# 通过person,反向查询写了几本book
class Person(models.Model);
    name = models.CharField(verbose_name='作者姓名', max_length=10)
    age = models.IntegerField(verbose_name='作者年龄')
class Book(models.Model):
    person = models.ForeignKey(Person, related_name='person_book',to_field='name')
    title = models.CharField(verbose_name='书籍名称', max_length=10)
    pubtime = models.DateField(verbose_name='出版时间')

# 方法1 基本
person = Person.objects.get(查询条件) # 获取作者信息,必须使用get获取到单一查询结果,filter获取到的是一个集合,不能使用
book = person.book_set.all() # 获取 person关联的所有书籍对象
# django默认每个主表的对象都有一个是外键的属性,可以通过它来查询到所有属于主表的子表信息,默认是以子表的名称小写加上_set()表示;返回的是一个querydict对象;

# 方法2 related_name
book = person.person_book.all()

verbose_name:
此名称在Django视图函数生成的form中,会做为展示的名称,不然的话,会展示数据库中的英文名,不利于阅读。

to_field:数据库中有外键时,显示的值

3 DateTimeField的区别

DateTimeField.auto_now_add: 创建时的时间,之后不会再更新,只读;
DateTimeField.auto_now: 每次修改model时的时间,只读;

4 数据库表中外键的使用

# views.py 通过双下划线获取到表中的具体信息
data_phone_all(request):
    if request.method == 'GET':
        phones = Phone.objects.values('id', 'IMEI', 'name', 'stage', 'num', 'note', 'birthday', 'can_borrow',
                                      'phone_dep__name','borrower__displayName')
        return JsonResponse(list(phones), safe=False)  # 将queryset变为可以Json化的list后再操作
# html 通过.实现获取信息
{% for phone in phones %}
    <tr>
        <td>{{ phone.id }}</td>
        <td>{{ phone.IMEI }}</td>
        <td>{{ phone.name }}</td>
        <td>{{ phone.stage }}</td>
        <td>{{ phone.num }}</td>
        <td>{{ phone.note }}</td>
        <td>{{ phone.can_borrow }}</td>
        <td>{{ phone.phone_dep.name}}</td>
    </tr>
{% endfor %}

model中定义的default与通过sql语句插入时的异同

在定义model时,可能会加入default、auto_time等选项,这在使用django的ORM新增记录时会自动添加,但是当使用sql insert语句时,不会自动添加,这时需要补全所有的字段才可以