第七章:Django开发中数据库的高级使用

一、关于Django中的字段方法名与MySQL中字段匹配

MySQL字段Django方法描述使用频率
intIntegerField常用
samllintSmallIntegerField
varcharCharField要指定长度常用
textTextField表示很多文字的时候使用
floatFloatField相当于python中float
dateDateField相当于python中的datetime.date,models.DateTimeField()常用于时间
booleanBooleanField如果没指定default,默认值是None
可空的booleanNullBooleanField表示可以为空的布尔值
邮箱EmailFieldmax_length=254
文件地址FilePathField
url字段URLField默认max_length=200
UUID字段UUIDFieldUUIDField(default=uuid.uuid4)常用

备注,直接利用上面的时间字段生成的时间会有因为时区差修改方式Django开发时区差处理方式

二、DjangoORM中的Field可以指定的字段

参数作用示例使用频率
null默认是False,如果指定为True,表示该字段可以为空id = IntegerField(null=True)常用
blank默认是False,如果指定为True,表示可以为空,blank是django给表单添加的
default给定默认值CharField(default=’xx’)常用
primary_key主键id = IntergerField(primary_key=True)常用
unique唯一的id = IntergerField(unique=True)常用
DateField.auto_now每次修改都会将当前时间更新进去,只有调用Model.save()方法才会调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及Time类才有的update_time = models.DateTimeField(auto_now=True,null=True)常用
DateField.auto_now_add第一次添加进去,都会将当前时间设置进去。以后修改,不会修改这个值create_time = models.DateTimeField(auto_now_add=True,null=True)常用

三、关于Django中外键ForeignKey的使用

  • 1、创建一个博客表,一个作者表,在博客表中添加一个外键约束,代码如下

    
    # 创建一个博客的数据模型
    
    class BlogModel(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=100, null=False)
        content = models.TextField(null=False)
        create_time = models.DateTimeField(auto_now_add=True,null=True)
        update_time = models.DateTimeField(auto_now=True,null=True)
        #博客的作者,外键约束到作者表
        author = models.ForeignKey('AuthorModel',null=True)
        #修改表名字
        class Meta:
            db_table = 'bolog'
    
    
    # 创建一个作者的数据模型
    
    class AuthorModel(models.Model):
        author_name = models.CharField(max_length=20,null=True)
        age = models.IntegerField(null=True)
    
        #修改表名
        class Meta:
            db_table = 'author'
  • 2、在博客表中添加数据的时候使用到外键

    
    # 新增文章视图
    
    def add(request):
        if request.method == 'GET':
            return render(request, 'books_add.html')
        elif request.method == 'POST':
            #获取表单的内容
            title = request.POST.get('title',None)
            content = request.POST.get('content',None)
            blogModel = BlogModel(title=title,content=content,author=AuthorModel.objects.get(id = 1))
            blogModel.save()
            #重定向到新增页面
            return HttpResponseRedirect('book_add')
        else:
            return HttpResponse(u'是不被处理的请求方式')
  • 3、正向查找(博客表查找作者)

    • 1、博客对作者(多对一的关系)
    • 2、作者对博客(一对多的关系)
    
    # 测试的视图
    
    def test(request):
        blogModel = BlogModel.objects.get(id = 9)
        print '*'*100
        print blogModel.author
        print blogModel.author.author_name
        print blogModel.author.age
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 4、反向查找(作者表查博客表)

    
    # 测试的视图
    
    def test(request):
        author = AuthorModel.objects.all().first()
        print '*'*100
        blogSet = author.blogmodel_set.all()
        print blogSet[0].title
        print '*'*100
        return HttpResponse(u'我是测试的')
    • 1、上面的反向查找用的是blogmodel_set(模型名_set),这个blogmodel_set(模型名_set)不是固定的,如果你反向查找BookModel就写bookmodel_set(模型名_set)
    • 2、使用查询返回的是一个QuerySet

四、多对多的关系,Django会默认创建一个中间表

  • 1、创建博客表与标签表,使用ManyToManyField进行多对多的关系

    
    # 创建一个博客的数据模型
    
    class BlogModel(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=100, null=False)
        content = models.TextField(null=False)
        create_time = models.DateTimeField(auto_now_add=True, null=True)
        update_time = models.DateTimeField(auto_now=True, null=True)
        # 博客的作者,外键约束到作者表
        author = models.ForeignKey('AuthorModel', on_delete=models.CASCADE, null=True)
        # 一个博客可能有多个标签,一个标签也可以用在多个博客上,(多对多的关系)
        tag = models.ManyToManyField('TagModel', null=True)
    
        # 修改表名字
        class Meta:
            db_table = 'bolog'
    
    
    
    # 创建一个标签的模型
    
    class TagModel(models.Model):
        name = models.CharField(max_length=100)
    
        # 修改表名
        class Meta:
            db_table = 'tag'
    
  • 2、为博客表添加数据的时候带上标签(使用add添加)

    
    # 测试的视图 
    
    def test(request):
        # 1.创建博客模型
        author = AuthorModel.objects.get(id = 2)
        blogModel = BlogModel(title='我是博客2',content='我是博客2的文章',author=author)
        # 2.博客模型数据保存
        blogModel.save()
        # 3.利用add添加tag
        tagModel = TagModel.objects.all()
        for tag in tagModel:
            blogModel.tag.add(tag)
        return HttpResponse(u'我是测试的')
    
  • 3、正向查找(博客表查询标签表)

    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.get(id = 12)
        print '*'*100
        # 由于这里查询的是多个所以要用.all()
        tags = blogModel.tag.all()
        html = ','.join(x.name for x in tags)
        print html
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 4、反向查找(标签查找博客表)

    
    # 测试的视图
    
    def test(request):
        tag= TagModel.objects.get(id = 3)
        tagSet = tag.blogmodel_set.all()
        print '*'*100
        html = ','.join(x.title for x in tagSet)
        print html
        print '*'*100
        return HttpResponse(u'我是测试的')

五、关于QuerySet上常用的方法,查询最后返回的依旧是QuerySet类型

  • 1、all()查找所有的数据[不演示]
  • 2、first()查找第一个[不演示]
  • 3、get(fieldname= xx)[不演示],当查询不到的时候就会报错,建议用filter,
  • 4、filter()查询数据

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.all().filter(name='python')
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 5、contains模糊查询

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.all().filter(name__contains='py')
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 6、exclude()排除查询

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.exclude(name__contains='py')
        print '*'*100
        html = ','.join(x.name for x in tag)
        print html
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 7、order_by()排序,默认是升序,如果要降序就-1操作

    
    # 测试的视图 
    
    def test(request):
        author = AuthorModel.objects.all().order_by('age')
        print '*'*100
        html = ','.join(x.author_name for x in author)
        print html
        print '*'*100
        return HttpResponse(u'我是测试的')
    
    # 测试的视图 
    
    def test(request):
        author = AuthorModel.objects.all().order_by('-age')
        print '*'*100
        html = ','.join(x.author_name for x in author)
        print html
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 8、values()QuerySet数据类型转换为字典返回(常用于ajax请求返回数据)

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.all().values()
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 9、count()计算多少条数,不要用length

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.count()
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 10、latest(field_name=None)获取距离最近的一条数据,其中field_name必须是时间字段

    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.latest('create_time')
        print '*'*100
        print blogModel.title
        print '*'*100
        return HttpResponse(u'我是测试的')
    
  • 11、earliest(field_name=None)latest()一样的,只是获取距离最久的那个

    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.earliest('create_time')
        print '*'*100
        print blogModel.title
        print '*'*100
        return HttpResponse(u'我是测试的') 
    
  • 12、last()first()一样的使用,获取最后一条数据

    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.all().last()
        print '*'*100
        print blogModel.title
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 13、update()更新数据

    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.filter(id=8).update(title='晨曦')
        print '*'*100
        print blogModel #返回的是发生变化的条数
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 14、delete()删除数据

六、根据条件查询数据

  • 1、exact相当于等号

    select * from 表名 where title = 'xx'
    
    # 测试的视图 
    
    def test(request):
        blogModel = BlogModel.objects.filter(title__exact='xx')
        blogModel1 = BlogModel.objects.filter(title= 'xx')
        print '*'*100
        print blogModel[0].content
        print blogModel1[0].content
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 2、iexactexact一样的使用,只是忽视大小写查询数据

  • 3、contains字段包含,用户模糊查询

    
    # 测试的视图 
    
    def test(request):
        tag = TagModel.objects.filter(name__contains='py')
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 4、icontainscontains一样的使用,只是忽视大小写的查询

  • 5、startswith以什么开始

    
    # 测试的视图 
    
    def test(request):
        # 计算以py开头的条数
        tag = TagModel.objects.filter(name__startswith='py').count()
        print '*'*100
        print tag
        print '*'*100
        return HttpResponse(u'我是测试的')
    
  • 6、istartswith跟上面的使用一样的,只是忽视大小写

  • 7、endswith以什么结尾,跟上面startswith用法一样的
  • 8、iendswith跟上面的使用一样的
  • 9、in判断是否在里面

    
    # 测试的视图 
    
    def test(request):
        # 查询年龄在18-20之间的
        author = AuthorModel.objects.filter(age__in=[18,20])
        print '*'*100
        print ','.join(x.author_name for x in author)
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 10、gt大于

    
    # 测试的视图
    
    def test(request):
        #查询年龄大于17的
        author = AuthorModel.objects.filter(age__gt=17)
        print '*'*100
        print ','.join(x.author_name for x in author)
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 11、gte大于等于,跟上面一样的使用

  • 12、lt小于,跟上面一样的使用
  • 13、lte小于等于,跟上面一样的使用
  • 14、range返回一个区间的,跟上面的in效果差不多,但是用于时间区域会更好

    
    # 测试的视图
    
    def test(request):
        startTime = '2017-07-23 14:54:52'
        endTime = '2017-07-23 16:09:38'
        # 计算一个事件区域的查询个数,包括头部与尾部
        blogModel = BlogModel.objects.filter(create_time__range=(startTime,endTime)).count()
        print '*'*100
        print blogModel
        print '*'*100
        return HttpResponse(u'我是测试的')
  • 15、isnull判断是否为空

  • 16、切片操作,跟python的使用一样的,只是不能为负数
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水痕01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值