• django 模型


    一、project 与app之间的关系
    
      1个project中可包含多个app
    
      eg:包含两个app的project的结构
    
      
    
      project:存放对各个app的配置
    
      app:真正的业务代码,包含models和views,以package的形式存在,
    
         容易完整移植到其他project,从而被多个project复用    
    
    二、用python代码定义表结构
    
      1、python通过models实现create table的操作:
    
    from django.db import models
    
    class Book(models.Model):
        name = models.CharField(max_length=50)
        pub_date = models.DateField()
      2、python代码定义表结构的好处
    
        1)无需考虑不同数据库平台的兼容性问题,无论是mysql,mongodb,redis
    
           从python代码create table的方式都是一样的
    
        2)开发者专注于python代码,不用再去写sql,减轻大脑负担
    
        3)django框架中有特定的数据类型, eg:email类型,url类型
    
        4)性能考虑:不用每次系统启动或者发起请求都要先检查一下数据库结构,而是
    
            可以根据python代码就知道了目标数据库的结构。
    
      3、缺点
    
        每次修改了python数据库结构后,需要手动修改数据库中的表结构
    
     三、测试models在django中的使用
    
      1、基本准备
    
        1)创建django project和app
    
          
    
        2)修改settings.py中的基本设置
    
          模板位置:
    
    TEMPLATE_DIRS = (
        os.path.join(BASE_DIR, 'templates'),
    )
          数据库连接:
    
    复制代码
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'django_db',
            'USER': 'root',
            'PASSWORD': 'feng',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        }
    }
    复制代码
          仅安装当前使用的app:
    
    复制代码
    INSTALLED_APPS = (
    #    'django.contrib.admin',
    #    'django.contrib.auth',
    #    'django.contrib.contenttypes',
    #    'django.contrib.sessions',
    #    'django.contrib.messages',
    #    'django.contrib.staticfiles',
        'model_test_app',
    )
    
    MIDDLEWARE_CLASSES = (
    #    'django.contrib.sessions.middleware.SessionMiddleware',
    #    'django.middleware.common.CommonMiddleware',
    #    'django.middleware.csrf.CsrfViewMiddleware',
    #    'django.contrib.auth.middleware.AuthenticationMiddleware',
    #    'django.contrib.messages.middleware.MessageMiddleware',
    #   'django.middleware.clickjacking.XFrameOptionsMiddleware',
    )
    复制代码
        执行ctrl+r+syndbc时,只会根据INSTALLED_APPS设置的app来检查
    
        对应的数据库表是否存在,其他没有设置的app不会被检查。
    
        3)此时数据库中的状态(之前有过其他project的测试数据)
    
          
    
        2、通过models.py定义表结构
    
         1)models.py中录入以下代码:
    
    复制代码
    from django.db import models
    
    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50)
        city = models.CharField(max_length=60)
        state_province = models.CharField(max_length=30)
        country = models.CharField(max_length=50)
        website = models.URLField()
    
    class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=40)
        email = models.EmailField()
    
    class Book(models.Model):
        title = models.CharField(max_length=100)
        authors = models.ManyToManyField(Author)
        publisher = models.ForeignKey(Publisher)
        publication_date = models.DateField()
    复制代码
        以上python定义表结构涉及到的知识点:
    
        a)字段类型:
    
            字符串类型,URL类型,Email类型,Date类型 
    
        b)多对多关系:
    
             authors = models.ManyToManyField(Author)
    
        c)外键:
    
             publisher = models.ForeignKey(Publisher)
    
        d)关于主键:
    
             无需显式指明主键,django会自动为每个模型生成一个自增的整数id作为主键
    
        2)通过python在数据库中创建表:
    
        a)检查model的语法和逻辑是否正确:ctrl+r+validate
    
            
    
        b)生成建表的sql语句:ctrl+r+sql
    
    复制代码
    "D:DevPlatformPyCharm 3.1.3in
    unnerw.exe" C:Python27python.exe "D:DevPlatformPyCharm 3.1.3helperspycharmdjango_manage.py" sql model_test_app D:/ProgramData/python/model_test
    BEGIN;
    CREATE TABLE `model_test_app_publisher` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `name` varchar(30) NOT NULL,
        `address` varchar(50) NOT NULL,
        `city` varchar(60) NOT NULL,
        `state_province` varchar(30) NOT NULL,
        `country` varchar(50) NOT NULL,
        `website` varchar(200) NOT NULL
    )
    ;
    CREATE TABLE `model_test_app_author` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `first_name` varchar(30) NOT NULL,
        `last_name` varchar(40) NOT NULL,
        `email` varchar(75) NOT NULL
    )
    ;
    CREATE TABLE `model_test_app_book_authors` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `book_id` integer NOT NULL,
        `author_id` integer NOT NULL,
        UNIQUE (`book_id`, `author_id`)
    )
    ;
    ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `author_id_refs_id_206f10ad` FOREIGN KEY (`author_id`) REFERENCES `model_test_app_author` (`id`);
    CREATE TABLE `model_test_app_book` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `title` varchar(100) NOT NULL,
        `publisher_id` integer NOT NULL,
        `publication_date` date NOT NULL
    )
    ;
    ALTER TABLE `model_test_app_book` ADD CONSTRAINT `publisher_id_refs_id_f51d29ce` FOREIGN KEY (`publisher_id`) REFERENCES `model_test_app_publisher` (`id`);
    ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `book_id_refs_id_6f49ea9b` FOREIGN KEY (`book_id`) REFERENCES `model_test_app_book` (`id`);
    
    COMMIT;
    
    Process finished with exit code 0
    复制代码
        此处多生成了一张表:model_test_app_book_authors,用于描述多对多关系
    
        c)同步sql语句到数据库: ctrl+r+syncdb
    
        
    
        运行之后数据库中的情况:
    
        
    
        说明:1、实际上可以修改自动生成表名的规则
    
           2、重复执行ctrl+r+syndbc是安全的,不会生成重复的表也不会冲掉旧数据
    
           3、只会根据INSTALLED_APPS设置的app来检查对应的数据库表是否存在
    
       3、基本数据访问
    
          views.py
    
    复制代码
    #coding:utf-8
    from django.shortcuts import render
    from django.shortcuts import render_to_response
    from model_test_app.models import Publisher
    
    # Create your views here.
    def db_op(request):
        #删除
        #Publisher.objects.filter(name='Apress').delete()
        Publisher.objects.all().delete()
        #新增
        p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
        city='Berkeley', state_province='CA', country='U.S.A.',
        website='http://www.apress.com/')
        p1.save()
        p2 = Publisher.objects.create(name="O'Reilly",
        address='10 Fawcett St.', city='Cambridge',
        state_province='MA', country='U.S.A.',
        website='http://www.oreilly.com/')
    
        #更新
        pub=Publisher.objects.get(name='Apress')
        pub.country='China'
        pub.save()
        #查询
        publisher_list = Publisher.objects.all()
        for publisher in publisher_list:
            print publisher.name,publisher.country
    
        return render_to_response('db_op.html', locals())
    复制代码
        db_op.html:
    
    复制代码
    <!DOCTYPE html>
    <html>
    <head>
        <title>数据库操作</title>
    </head>
    <body>
        <p>操作结果:</p>
        <p>
            <ul>
                {% for publisher in publisher_list %}
                <li>{{ publisher.name }}, {{publisher.country}}</li>
                {% endfor %}
            </ul>
        </p>
    </body>
    </html>
    复制代码
          执行结果:
    
          页面:
    
         
    
          后台输出:
    
         
    
        4、模型中的__unicode__()方法:
    
         用于自定义输出“模型”的字符串内容,类似于java中的toString方法
    
         views.py中的输出操作:
    
    复制代码
    def db_op(request):
        #查询
        publisher_list = Publisher.objects.all()
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
        未添加__unicode__()方法时:
    
        
    
        增加了__unicode__()方法时:
    
    复制代码
    from django.db import models
    
    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50)
        city = models.CharField(max_length=60)
        state_province = models.CharField(max_length=30)
        country = models.CharField(max_length=50)
        website = models.URLField()
    
        #def __unicode__(self):
            #return self.name
        def __unicode__(self):
            return u'%s, %s'%(self.name,self.country)
    复制代码
        
    
       5、关于update操作中的p.save()
    
        并不是只更新修改过的那个字段,所有的字段都会被更新
    
       6、django中实现where条件
    
        1)查询中对字段进行过滤
    
    复制代码
    def db_op(request):
        #查询
        publisher_list = Publisher.objects.filter(name='Apress',country='China')
    
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
         执行结果:
    
         
    
        2)like关键词在django中的实现
    
    复制代码
    def db_op(request):
        #查询
        publisher_list = Publisher.objects.filter(name__contains='eil')
    
        #publisher_list = Publisher.objects.all()
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
        相当于:where name like '%eil%'
    
        执行结果:
    
        
    
        3)get方法获取单条记录:
    
           a)恰好返回1条记录时
    
    复制代码
    def db_op(request):
    
        try:
            pub=Publisher.objects.get(name__contains='eil')
        except:
            print '获取单条记录发生异常'
        else:
            print pub.name
    
        return render_to_response('db_op.html', locals())
    复制代码
          
    
           b)返回两条记录时
    
    复制代码
    def db_op(request):
    
        try:
            pub=Publisher.objects.get(name__contains='e')
        except:
            print '获取单条记录发生异常'
        else:
            print pub.name
    
        return render_to_response('db_op.html', locals())
    复制代码
          
    
          c)没有记录返回时
    
    复制代码
    def db_op(request):
    
        try:
            pub=Publisher.objects.get(name__contains='eeeeeee')
        except:
            print '获取单条记录发生异常'
        else:
            print pub.name
    
        return render_to_response('db_op.html', locals())
    复制代码
          
    
         4)排序     
    
    复制代码
    def db_op(request):
        #升序
        publisher_list=Publisher.objects.order_by("name","country")
        print publisher_list
        #降序
        publisher_list2=Publisher.objects.order_by("-name","country")
        print publisher_list2
    
        return render_to_response('db_op.html', locals())
    复制代码
          执行结果:
    
          
    
          模型中指定默认排序规则:
    
    复制代码
    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50)
        city = models.CharField(max_length=60)
        state_province = models.CharField(max_length=30)
        country = models.CharField(max_length=50)
        website = models.URLField()
    
        def __unicode__(self):
            return u'%s, %s'%(self.name,self.country)
    
        class Meta:
            ordering = ['-name']
    复制代码
    复制代码
    def db_op(request):
    
        publisher_list=Publisher.objects.all()
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
        执行结果:
    
        
    
          5)where和order by同时使用
    
    复制代码
    def db_op(request):
    
        publisher_list=Publisher.objects.filter(name="Apress").order_by("name")
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
         
    
        6)limit的实现
    
    复制代码
    def db_op(request):
        #返回单个记录
        pub=Publisher.objects.order_by("name")[0]
        print pub
    
        #返回记录列表
        publisher_list=Publisher.objects.order_by("name")[0:100]
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
         执行结果:
    
         
    
        7)更新记录中的某些字段,而不是所有字段
    
           使用结果集QuerySet的update()方法,而不是p.save()
    
    复制代码
    def db_op(request):
        #返回记录列表
        affectRowCount=Publisher.objects.filter(name__contains='e').update(country='Japan')
        print affectRowCount
    
        publisher_list=Publisher.objects.all()
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
          执行结果:
    
          
    
        8)删除一些记录,而不是单条记录
    
           使用 使用结果集QuerySet的delete()方法,而不是先get单条p,再p.delete()
    
    复制代码
    def db_op(request):
        #返回记录列表
        affectRowCount=Publisher.objects.filter(name='Apress').delete()
        print affectRowCount
    
        publisher_list=Publisher.objects.all()
        print publisher_list
    
        return render_to_response('db_op.html', locals())
    复制代码
  • 相关阅读:
    Salt-ssh批量自动安装被控端salt-mini
    Saltstack配置管理
    gitlab的安装和基本维护
    Git的杀手级功能之 一 远程仓库
    分布式版本控制系统-git
    Linux查看服务器公网ip的方法
    vmware fusion 10序列号
    python3.6.4的importlib模块重载用法
    设置PyCharm中的Python代码模版
    MacOs执行SQL出错(mysql)
  • 原文地址:https://www.cnblogs.com/skying555/p/4460475.html
Copyright © 2020-2023  润新知