zoukankan      html  css  js  c++  java
  • [Python自学] day-19 (2) (Django-ORM)

    一、ORM的分类

    ORM一般分为两类:

    1.DB first:先在DB中创建数据库、表结构,然后自动生成代码中的类。在后续操作中直接在代码中操作相应的类即可。

    2.Code first:直接在代码中实现各种类,然后执行,代码自动在DB中创建对应的数据库和表结构。

    最常用的是后者,即Code First类型的ORM。例如 [Python自学] day-12 (Mysql、事务、索引、ORM) 中的SQLAlchemy,我们即将要了解的Django ORM也属于Code first。

    二、利用ORM创建表

    在我们不修改Django数据库配置的情况下,Django默认使用的数据库是sqlite3:

    我们暂且使用该默认的数据库。

    1.在cmdb APP中的models.py中创建一个类

    from django.db import models
    
    
    class UserInfo(models.Model):
        # ORM会自动帮我们生成一个id列,是自增的
    
        # 生成cmdb_userinfo表,里面含有username和password两列
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=64)

    2.使用命令行在数据库中生成表

    python manage.py makemigrations

    理论上,会在cmdb/migrations中生成一个临时文件。但是这里并未生成,这是因为cmdb这个APP的models.py并未装载到Django中,所以Django找不到该models.py。

    3.配置settings.py(重要)

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'cmdb',
    ]

    4.再次执行命令行

    D:pycharm_workspacesecondsite>d:Dev_appsAnaconda5.3.0python.exe manage.py makemigrations
    Migrations for 'cmdb':
      cmdbmigrations001_initial.py
        - Create model UserInfo

    我们查看cmdb/migrations目录:

    然后执行命令:

    D:pycharm_workspacesecondsite>d:Dev_appsAnaconda5.3.0python.exe manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, cmdb, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying cmdb.0001_initial... OK
      Applying sessions.0001_initial... OK

    我们可以看到,Django除了帮我们执行了cmdb.0001_initial,还执行了一大堆其他的东西,这些东西是Django默认帮我们生成的表,包括sessions等常用的东西。

    三、配置使用Mysql数据库

    查看settings.py:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

    可以看到,这里配置使用数据库后端为sqlite3。

    我们将其修改为Mysql:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'dbname',  # 数据库名,这个django不能帮我们创建,需要我们手工创建
            'USER': 'root',  # 登录用户名
            'PASSWORD': 'xxx',  # 登录密码
            'HOST': '',  # IP
            'PORT': '',  # port
        }
    }

    修改完settings.py后,执行命令,即可在mysql中创建表:

    python manage.py makemigrations
    python manage.py migrate

    特别注意:(非常重要)

    Django连接mysql默认使用的事MySQLdb模块,但是在python3中还没有这个模块。

    我们需要在工程目录的__init__.py:

    写入以下代码:

    import pymysql
    
    pymysql.install_as_MySQLdb()

    四、查看sqlite3数据库

    使用Navicat软件连接sqlite3数据库,查看Django-ORM为我们创建的表。

    1.运行Navicat软件:

    2.连接sqlite3数据库:

    3.查看数据库中的表

    我们可以从中找到我们在cmdb/models.py中使用类创建的表,这里叫 cmdb_userinfo

    4.查看cmdb_userinfo表

    可以看到,表中有三个列,id列(django自动创建,自增的)、username列和password列。

     

    五、ORM插入数据(基础)

    我们写一个orm测试页面。

    1.在cmdb/urls.py中添加一个映射关系:

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login', views.login),
        path('home', views.home),
        # path('mypage', views.MyPage.as_view()),
        path('mypage12376sjhdfjnwjer', views.MyPage.as_view(), name='mypage'),
        path('users', views.user_page),
        re_path('details-(d+).html', views.details),
        path('orm', views.orm_test),
    ]

    2.在视图函数中使用ORM插入数据:

    # 导入cmdb的models模块
    from cmdb import models
    
    
    def orm_test(request):
        # 在表中插入一条数据
        models.UserInfo.objects.create(
            username='root',
            password='123456'
        )
        return HttpResponse('ok')

    另外一种方式:

    def orm_test(request):
        obj = models.UserInfo(username='alex', password='123')
        obj.save()
        return HttpResponse('ok')

    第三种方式(第一种的变种,其实就是拆包):

    def orm_test(request):
        # 在表中插入一条数据
        dic = {'username': 'eric', 'password': '123'}
        models.UserInfo.objects.create(**dic)
        return HttpResponse('ok')

    3.请求http://127.0.0.1/cmdb/orm

    4.查看数据库中的cmdb_userinfo表

    我们可以看到,数据已经成功插入表中。

    六、ORM查询数据(基础)

    1.查询表中所有数据(相当于select * from cmdb_userinfo;):

    def orm_test(request):
        # 查询数据,返回的result是QuerySet类型,实际上相当于一个列表,每个元素是一个对象,相当于 select * from cmdb_userinfo;
        result = models.UserInfo.objects.all()
        # 便利result中的每个对象,其中每列对应一个成员属性
        for row in result:
            print(row.id, row.username, row.password)
        return HttpResponse('ok')

    2.查询部分列(相当于 select username,password from cmdb_userinfo;):

    def orm_test(request):
        # result同样是QuerySet,但每个元素变成了字典
        result = models.UserInfo.objects.all().values('username','password')
        # 遍历result中的每个对象
        for row in result:
            print(row['username'], row['password'])
        return HttpResponse('ok')

    当然,我们如果将result通过render函数合并进模板,在模板语言中也要按result的结构来获取数据。

    除了使用values()来获取部分列,还可以使用values_list('username','password'):

    def orm_test(request):
        # result同样是QuerySet,但每个元素变成了元组
        result = models.UserInfo.objects.all().values_list('username','password')
        # 遍历result中的每个对象
        for row in result:
            print(row[0], row[1])
        return HttpResponse('ok')

    3.过滤查询(相当于 select * from cmdb_userinfo where username='alex';):

    def orm_test(request):
        # 过滤查询,过滤出username='alex'的记录
        result = models.UserInfo.objects.filter(username='alex')
        # 便利result中的每个对象,其中每列对应一个成员属性
        for row in result:
            print(row.id, row.username, row.password)
        return HttpResponse('ok')

    如果是多个过滤条件组成交集(AND),则为:

    models.UserInfo.objects.filter(username='alex', password='123')

    七、ORM删除数据(基础)

    def orm_test(request):
        # 删除所有数据
        models.UserInfo.objects.all().delete()
        # 删除过滤数据
        models.UserInfo.objects.filter(username='alex').delete()
        
        return HttpResponse('ok')

    八、ORM更新数据(基础)

    1.基本更新操作

    def orm_test(request):
        # 修改所有条目的password
        models.UserInfo.objects.all().update(password='6666')
        # 修改部分条目的password
        models.UserInfo.objects.filter(username='alex').update(password='10000')
    
        return HttpResponse('ok')

    2.同时更新多个数据

    def orm_test(request):
        # 修改部分条目的password
        models.UserInfo.objects.filter(id=3).update(password='10000', username='Leo')
    
        return HttpResponse('ok')

    九、实现基于数据库的用户登录

    1.login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Login</title>
        <link rel="stylesheet" href="/static/commons.css"/>
        <style>
            label{
                width: 80px;
                text-align: right;
                display: inline-block;
            }
            .error_span{
                color: red;
            }
        </style>
    </head>
    <body class="common">
        <form action="/cmdb/login/" method="post">
            <p>
                <label for="username">用户名:</label>
                <input id="username" type="text" name="user"/>
                <span class="error_span">{{ user_error }}</span>
            </p>
            <p>
                <label for="password">密码:</label>
                <input id="password" type="password" name="pwd"/>
                <input type="submit" value="提交"/>
                <span class="error_span">{{ pwd_error }}</span>
            </p>
        </form>
        <script src="/static/jquery-1.12.4.js"></script>
    </body>
    </html>

    2.cmdb/urls.py映射关系

    urlpatterns = [
        path('login/', views.login),
    ]

    3.cmdb/views.py视图函数

    def login(request):
        if request.method == 'POST':
            username = request.POST.get('user', None)
            password = request.POST.get('pwd', None)
    
            pwd_error_msg = ''
            # 从数据库中验证用户名密码是否存在,filter获取的是一个列表,first是取列表的第一个元素,即一条记录或者None
            obj = models.UserInfo.objects.filter(username=username, password=password).first()
            if obj:
                return redirect('http://www.baidu.com')
            else:
                pwd_error_msg = "账号或密码不正确"
                return render(request, 'login.html', {"pwd_error": pwd_error_msg})

    4.实现效果

    输入账号密码提交给后台,然后从数据库验证,如果正确,则跳转到www.baidu.com,如果不正确则跳转回当前页面,重新输入。

    十、ORM修改表结构

    修改表结构,直接对app/models.py中的类进行修改就可以了。

    修改完后都要执行以下命令:

    python manage.py makemigrations
    python manage.py migrate

    1.修改数据类型(长度)

    class UserInfo(models.Model):
        # ORM会自动帮我们生成一个id列,是自增的
    
        # 生成UserInfo表,里面含有username和password两列
        username = models.CharField(max_length=32)
        #password = models.CharField(max_length=64)
        password = models.CharField(max_length=80)   # 将密码的长度修改为80

    如果将长度改短,则如果数据超出长度,会丢失。

    2.增加列

    class UserInfo(models.Model):
        # ORM会自动帮我们生成一个id列,是自增的
    
        username = models.CharField(max_length=32)
        #password = models.CharField(max_length=64)
        password = models.CharField(max_length=80)   # 将密码的长度修改为80
        email = models.CharField(max_length=100)  # 增加一列email

    默认增加的列是不能为空的,所以在执行"python manage.py makemigrations"命令时会弹出提示:

    (venv) D:pycharm_workspacesecondsite>d:Dev_appsAnaconda5.3.0python.exe manage.py makemigrations
    You are trying to add a non-nullable field 'email' to userinfo without a default; we can't do that (the database needs something to populate existing rows).
    Please select a fix:
     1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
     2) Quit, and let me add a default in models.py
    Select an option: 1
    Please enter the default value now, as valid Python
    The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
    Type 'exit' to exit this prompt
    >>>  "xxx@email.com"
    Migrations for 'cmdb':
      cmdbmigrations002_auto_20191218_1319.py
        - Add field email to userinfo
        - Alter field password on userinfo

    选择1,然后输入默认值。接着再执行"python manage.py migrate"命令。

    执行列可以为空:

    class UserInfo(models.Model):
        # ORM会自动帮我们生成一个id列,是自增的
    
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=80)
        email = models.CharField(max_length=100, null=True)  # 增加一列email,允许为空

    使用"null=True"设置列允许为空。

    3.删除列

    class UserInfo(models.Model):
        # ORM会自动帮我们生成一个id列,是自增的
    
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=80)
        #email = models.CharField(max_length=100, null=True)  # 删除email列

    注释或删除需要删除的列对应属性。然后重新

    十一、ORM字段类型

    在mysql数据库中,有字符串、数字、二进制等类型,在Django的ORM中也有对应的字段类型。

    前面我们使用了CharField类型:

    username = models.CharField(max_length=32)

    ORM提供的数据类型:

    AutoField(Field)
        - int自增列,必须填入参数 primary_key=True
    
    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True
    
        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models
    
        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)
    
        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)
    
    SmallIntegerField(IntegerField):
        - 小整数 -3276832767
    
    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 032767
    IntegerField(Field)
        - 整数列(有符号的) -21474836482147483647
    
    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 02147483647
    
    BigIntegerField(IntegerField):
        - 长整型(有符号的) -92233720368547758089223372036854775807
    
    自定义无符号整数字段
    
        class UnsignedIntegerField(models.IntegerField):
            def db_type(self, connection):
                return 'integer UNSIGNED'
    
        PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
            'AutoField': 'integer AUTO_INCREMENT',
            'BigAutoField': 'bigint AUTO_INCREMENT',
            'BinaryField': 'longblob',
            'BooleanField': 'bool',
            'CharField': 'varchar(%(max_length)s)',
            'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
            'DateField': 'date',
            'DateTimeField': 'datetime',
            'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
            'DurationField': 'bigint',
            'FileField': 'varchar(%(max_length)s)',
            'FilePathField': 'varchar(%(max_length)s)',
            'FloatField': 'double precision',
            'IntegerField': 'integer',
            'BigIntegerField': 'bigint',
            'IPAddressField': 'char(15)',
            'GenericIPAddressField': 'char(39)',
            'NullBooleanField': 'bool',
            'OneToOneField': 'integer',
            'PositiveIntegerField': 'integer UNSIGNED',
            'PositiveSmallIntegerField': 'smallint UNSIGNED',
            'SlugField': 'varchar(%(max_length)s)',
            'SmallIntegerField': 'smallint',
            'TextField': 'longtext',
            'TimeField': 'time',
            'UUIDField': 'char(32)',
    
    BooleanField(Field)
        - 布尔值类型
    
    NullBooleanField(Field):
        - 可以为空的布尔值
    
    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度
    
    TextField(Field)
        - 文本类型
    
    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制  (过期)
    
    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
    
    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL
    
    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
    
    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字
    
    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
    
    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹
    
    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD
    
    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]
    
    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
    
    FloatField(Field)
        - 浮点型
    
    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度
    
    BinaryField(Field)
        - 二进制类型

    上述提供的字段类型主要分为四类:

    • 字符串
    • 数字
    • 时间
    • 二进制

    注意:我们可以看到一些URLField、EmailField,看似有语法验证的功能,但实际上就是一个普通的CharField。

    为什么要提供这种特殊的字段,是因为Django为我们提供的admin后台管理组件要使用他们,当我们创建这样的字段时,如果使用admin进行数据库后台管理,那么页面上就会进行语法验证(对于数据库还是varchar)。

    AutoField:

    from django.db import models
    
    
    class UserInfo(models.Model):
        # 手工创建自增id列(手工创建了,Django就不会自动创建)
        uid = models.AutoField(primary_key=True)
    
        # 生成UserInfo表,里面含有username和password两列
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=80)

    使用AutoField可以手工创建自增id列,必须指定为主键。

    十二、ORM字段的参数

    ORM提供的字段类型,可以使用以下参数:

    null                数据库中字段是否可以为空  eg. null=True 允许为空
    db_column           数据库中字段的列名  eg. db_column='c_name' 设置列名为c_name
    db_tablespace
    default             数据库中字段的默认值  eg. default='content' 默认值为content
    primary_key         数据库中字段是否为主键    eg.  primary_key=True 设置为主键
    db_index            数据库中字段是否可以建立索引  eg. db_index=True 建立索引
    unique              数据库中字段是否可以建立唯一索引  eg. unique=True 唯一索引
    unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引  eg. 2019年1月1日11时11分11秒 只对其中的日期做索引
    unique_for_month    数据库中字段【月】部分是否可以建立唯一索引   eg. 只对月份做索引
    unique_for_year     数据库中字段【年】部分是否可以建立唯一索引   eg. 只对年份做索引
    
    auto_now            用于时间字段,在更新数据时自动插入当前时间(也包括新插入数据时)
                        eg.
                            uptime = models.DateTimeTield(auto_now=True, null=True)
                        要使该时间更新,不能使用:
                            obj = models.UserInfo.objects.filter(id=1).update(password='123')
                        必须使用:
                            obj = models.UserInfo.objects.filter(id=1).first()
                            obj.password="123"
                            obj.save()  # 此时uptime才会更新
    
    auto_now_add        用于时间字段,在插入数据时自动插入当前时间
                        eg.
                            ctime = models.DateTimeTield(auto_now_add=True, null=True)
    
    verbose_name        Admin中显示的字段名称  eg. verbose_name="用户名" 页面上就不会显示"username",而是显示"用户名"
    blank               Admin中是否允许用户输入为空  eg. blank=True 页面上不填内容提交时,不会进行内容为空的提示
    editable            Admin中是否可以编辑  eg. editable=False 页面上相应输入框消失(不可编辑)
    help_text           Admin中该字段的提示信息  eg.  help_text="输入密码" 页面上会在密码输入框下显示"输入密码"提示
    choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                        如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
    
    error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                        字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                        如:{'null': "不能为空.", 'invalid': '格式错误'}
    
    validators          自定义错误验证(列表类型),从而定制想要的验证规则
                        from django.core.validators import RegexValidator
                        from django.core.validators import EmailValidator,URLValidator,DecimalValidator,
                        MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                        如:
                            test = models.CharField(
                                max_length=32,
                                error_messages={
                                    'c1': '优先错信息1',
                                    'c2': '优先错信息2',
                                    'c3': '优先错信息3',
                                },
                                validators=[
                                    RegexValidator(regex='root_d+', message='错误了', code='c1'),
                                    RegexValidator(regex='root_112233d+', message='又错误了', code='c2'),
                                    EmailValidator(message='又错误了', code='c3'), ]
                            )

    其中有很大一部分是专门用于操作Django admin后台管理页面的。

    十三、ORM外键

    例如有两个表:用户表和部门表

    from django.db import models
    
    
    class GroupInfo(models.Model):
        gid = models.AutoField(primary_key=True)
        groupname = models.CharField(max_length=32)
    
    
    class UserInfo(models.Model):
        # 手工创建自增id列(手工创建了,Django就不会自动创建)
        uid = models.AutoField(primary_key=True)
        # 添加一个列,使用外键,外键为GroupInfo表中的gid列(该列的值必须是唯一的),如果不写to_field则默认使用主键,默认值为1
        group = models.ForeignKey('GroupInfo', to_field='gid', default=1)
        # 生成UserInfo表,里面含有username和password两列
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=80)

    特别注意:虽然我们定义外键时使用的变量名叫"group",但Django帮我们在表里生成的实际的列名叫做"group_id"。如下图所示:

    当我们查询某个用户信息时,联合UserGroup表一起查询该用户所在group:

    def orm_test(request):
        # 向UserGroup表中插入一个group (gid=1,groupname='Dev')
        models.UserGroup.objects.create(groupname="Dev")
        # 向UserInfo表中插入一个user (uid=1,username='Leo',password='123',group_id=1),注意这里要使用真实列名group_id
        models.UserInfo.objects.create(username="Leo", password='123', group_id=1)
    
        # 联合查询UserInfo以及UserGroup
        # 获取第一个用户,这里只有一个用户Leo
        obj = models.UserInfo.objects.filter(uid=1).first()
        # 打印用户的用户名、密码(这些内容都在UserInfo表中)
        print(obj.username)
        print(obj.password)
        # 这里注意,group是外键,指向UserGroup表,所以这里的group属性是一个对象(UserGroup表的一条记录),我们通过该对象来获取groupname
        print(obj.group.groupname)
    
        return HttpResponse('ok')

    当我们查询一个带有外键的表的记录时,Django会自动关联查询外键指向的表(UserGroup),并将对应的记录存放到一个对象中(UserGroup一条记录),我们通过该记录可以获取外键指向的表中的信息(groupname)。

    def orm_test(request):
        # 查询数据,返回的result是QuerySet类型,实际上相当于一个列表,每个元素是一个对象,相当于 select * from cmdb_userinfo;
        result = models.UserInfo.objects.all()
        # 便利result中的每个对象,其中每列对应一个成员属性
        for row in result:
            print(row.id, row.username, row.password)
        return HttpResponse('ok')
  • 相关阅读:
    NGINX之——配置HTTPS加密反向代理訪问–自签CA
    AVPlayer的使用,带缓冲
    优化数据页面(15)——表题应当准确精练
    FFmpeg基础库编程开发学习笔记——音频常见格式及字幕格式
    【版本号公布】Jeecg-P3 1.0 公布,J2EE微服务框架(插件开发)
    猫猫学iOS之UILabel设置圆角不成功所做调控更改
    linux strace-跟踪进程的系统调用或是信号产生情况,lstrace-跟踪己丑年调用库函数情况,进程跟踪调试命令
    text
    sql server 2008 开启1433端口,开启远程连接
    openStack kvm 虚拟机CPU颗粒化控制
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/12056917.html
Copyright © 2011-2022 走看看