zoukankan      html  css  js  c++  java
  • Django——模型基础(单表)

    1.ORM

    在MVC或者说MTV设计模式中,模型(M)代表对数据库的操作。但操作数据库需要专门的SQL语句,而Python程序员不是专业的DBA,写的SQL语句可能有点次,于是就有人想到用python语法来操作,这就是ORM。

    ORM 即:对象—关系—映射(从https://www.cnblogs.com/huang-yc/p/9652935.html盗来一张图,顺便吹下这位博主!)

    简单又不太专业的说就是通过映射关系使得一个python语句对应一个SQL语句,这样python程序员无需关心ORM内部的细节,也不用很了解SQL语法,只要通过python就可以操作数据库了。

    把代码敲一遍:

    SQL语句

    # SQL的表
    
    # 创建表:
    CREATE TABLE employee(
        id INT PRIMARY KEY auto_increment,
        name VARCHAR(20),
        gender BIT default 1,
        birthday DATA,
        department VARCHAR(20),
        salary DECIMAL (8,2) unsigned
        );
    
    # 表记录
    
    # 添加一条表记录:
    INSERT employee(name,gender,birthday,salary,department) VALUES("Alex",1,"1985-12-12",8000,"保洁部");
    
    # 查询一条表记录:
    SELECT * FROM employee WHERE age=24;
    
    # 更新一条表记录:
    UPDATE employee SET birthday="1989-10-10" WHERE id=1;
    
    # 删除一条表记录:
    DELETE FROM employee WHERE name="Alex"
    View Code

    Python语句

    # python的类
    
    class Employee(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        gender=models.Booleanfield()
        birthday=models.DateField()
        depatment=models.CharField(max_length=32)
        salary=models.DecimalField(max_digits=8,decimal_places=2)
    
    # python类对象
    
    # 添加一条表记录
    emp=Employee(name="Alex",gender=True,birthday="1985-12-12",department="保洁部")
    emp.save()
    
    # 查询一条表记录
    Employee.objects.filter(age=24)
    
    # 更新一条表记录
    Employee.objects.filter(id=1).update(birthday="1989-10-10")
    
    # 删除一条表记录
    Employee.objects.filter(name="Alex").delete()
    View Code

     2.单表操作

     如前所说每个模型映射为一张数据库中的表,基本原则如下:

    • 每个模型在Django中的存在形式为一个Python类
    • 每个模型都是django.db.models.Model的子类
    • 模型的每个字段(属性)代表数据表的某一列
    • Django将自动为你生成数据库访问API

    2.1创建表

    跟上面一样,上代码:

    from django.db import models
    
    # Create your models here.
    
    
    class User(models.Model):
        username = models.CharField( max_length=20, unique=True)
        password = models.CharField( max_length=256)
        email = models.EmailField()
        create_time = models.DateTimeField( auto_now_add=True)

    2.2常用字段和参数

    字段是模型中最重要的内容之一,也是唯一必须的部分。字段在Python中表现为一个类属性,体现了数据表中的一个列。字段决定数据库中对应列的数据类型,每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。这里就列出一些常用的或常见的。

    常见字段:

    类型                     说明
    
    AutoField       # 一个自动增加的整数类型字段。通常你不需要自己编写它,Django会自动帮你添加字段:id = models.AutoField(primary_key=True),这是一个自增字段,从1开始计数。如果你非要自己设置主键,那么请务必将字段设置为primary_key=True。Django在一个模型中只允许有一个自增字段,并且该字段必须为主键!
    BooleanField      # 布尔值类型。默认值是None。在HTML表单中体现为CheckboxInput标签。如果要接收null值,请使用NullBooleanField。
    CharField       # 字符串类型。必须接收一个max_length参数,表示字符串长度不能超过该值。默认的表单标签是input text。最常用的filed,没有之一!
    CommaSeparatedIntegerField       # 逗号分隔的整数类型。必须接收一个max_length参数。常用于表示较大的金额数目,例如1,000,000元。
    DateField        # class DateField(auto_now=False, auto_now_add=False, **options)日期类型。一个Python中的datetime.date的实例。在HTML中表现为TextInput标签。在admin后台中,Django会帮你自动添加一个JS的日历表和一个“Today”快捷方式,以及附加的日期合法性验证。两个重要参数:(参数互斥,不能共存) auto_now:每当对象被保存时将字段设为当前日期,常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,它是不可修改的)。设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。例子:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。
    DateTimeField       # 日期时间类型。Python的datetime.datetime的实例。与DateField相比就是多了小时、分和秒的显示,其它功能、参数、用法、默认值等等都一样。
    DecimalField        # 固定精度的十进制小数。相当于Python的Decimal实例,必须提供两个指定的参数!参数max_digits:最大的位数,必须大于或等于小数点位数 。decimal_places:小数点位数,精度。 当localize=False时,它在HTML表现为NumberInput标签,否则是text类型。例子:储存最大不超过999,带有2位小数位精度的数,定义如下:models.DecimalField(..., max_digits=5, decimal_places=2)。
    DurationField     # 持续时间类型。存储一定期间的时间长度。类似Python中的timedelta。在不同的数据库实现中有不同的表示方法。常用于进行时间之间的加减运算。但是小心了,这里有坑,PostgreSQL等数据库之间有兼容性问题!
    EmailField     # 邮箱类型,默认max_length最大长度254位。使用这个字段的好处是,可以使用DJango内置的EmailValidator进行邮箱地址合法性验证。
    FileField    # class FileField(upload_to=None, max_length=100, **options)上传文件类型,   http://www.liujiangblog.com/course/django/95
    FilePathField     # 文件路径类型     http://www.liujiangblog.com/course/django/95
    FloatField        # 参考整型     http://www.liujiangblog.com/course/django/95
    ImageField     # 图像类型     http://www.liujiangblog.com/course/django/95
    IntegerField      # 整数类型,最常用的字段之一。取值范围-2147483648到2147483647。在HTML中表现为NumberInput标签。
    GenericIPAddressField         # class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[source],IPV4或者IPV6地址,字符串形式,例如192.0.2.30或者2a02:42fe::4在HTML中表现为TextInput标签。参数protocol默认值为‘both’,可选‘IPv4’或者‘IPv6’,表示你的IP地址类型。
    NullBooleanField      #   类似布尔字段,只不过额外允许NULL作为选项之一。
    TextField      # 大量文本内容,在HTML中表现为Textarea标签,最常用的字段类型之一!如果你为它设置一个max_length参数,那么在前端页面中会受到输入字符数量限制,然而在模型和数据库层面却不受影响。只有CharField才能同时作用于两者。
    TimeField         # 时间字段,Python中datetime.time的实例。接收同DateField一样的参数,只作用于小时、分和秒。
    URLField        # 一个用于保存URL地址的字符串类型,默认最大长度200。
    UUIDField      #  用于保存通用唯一识别码(Universally Unique Identifier)的字段。使用Python的UUID类。在PostgreSQL数据库中保存为uuid类型,其它数据库中为char(32)。这个字段是自增主键的最佳替代品,后面有例子展示。 

    常用参数:

    参数                说明
    
    null    # 该值为True时,Django在数据库用NULL保存空值。默认值为False。
    blank    # True时,字段可以为空。默认False。和null参数不同的是,null是纯数据库层面的,而blank是验证相关的,与数据库无关。所以要小心一个null为False,blank为True的字段接收到一个空值可能会出bug或异常。
    choices       # 用于页面上的选择框标签,需要先提供一个二维的二元元组,第一个元素表示存在数据库内真实的值,第二个表示页面上显示的具体内容。
    default   # 字段的默认值,可以是值或者一个可调用对象。如果是可调用对象,那么每次创建新对象时都会调用
    primary_key     # 如果你为某个字段设置了primary_key=True,则当前字段变为主键,并关闭Django自动生成id主键的功能。primary_key=True隐含null=False和unique=True的意思。一个模型中只能有一个主键字段!
    db_index         # 该参数接收布尔值。如果为True,数据库将为该字段创建索引。
    unique      # 设为True时,在整个数据表内该字段的数据不可重复。
     # 注意:对于ManyToManyField和OneToOneField关系类型,该参数无效。
     # 注意: 当unique=True时,db_index参数无须设置,因为unqiue隐含了索引。
    
    verbose_name    # 为字段设置一个人类可读,更加直观的别名。

    2.3settings配置

    import pymysql
    pymysql.install_as_MySQLdb()
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'myblog',      # 数据库名
            'USER': 'root',          # 数据库的用户名
            'PASSWORD': 'pwd',      # 数据库密码
            'HOST': '',        # 主机IP,默认本机
            'PORT': ''         # 主机端口,默认“3306”
        }
    }
    View Code

    要注意:NAME即数据库的名字,在mysql连接前该数据库必须提前手动创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。

     最后通过两条数据库迁移命令即可在指定的数据库中创建表:

    python manage.py makemigrations
    python manage.py migrate

    2.4记录表的增、删、改

    增:两种方式

    # 方式一:create
    user = models.User.objects.create(username="Alex",password="pwd",email="alex@163.com")      # create方法的返回值即为新插入表的名为Alex的对象
    
    #方式二:save
    user = models.User(username="Alex",password="pwd",email="alex@163.com")
    user.save()

    删:

    删除对象使用的是对象的delete()方法。

    user.delete()

    你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。
    例如,下面的代码将删除 pub_date 是2005年的Article对象:

    models.Article.objects.filter(pub_date__year=2005).delete()

    当Django删除一个对象时,它默认使用SQL的ON DELETE CASCADE约束,也就是说,任何有外键指向要删除对象的对象将一起被删除。例如:

    u = models.User.objects.get(pk=1)
    # 下面的动作将删除该条Blog和所有的它关联的Article对象
    u.delete()

    这种级联的行为可以通过的ForeignKey的on_delete参数自定义,如果不想级联删除,就可以设置on_delete为其他方式,如:

    user = models.ForeignKey(to='User', on_delete=models.SET_NULL, blank=True, null=True)

    注意,delete()是唯一没有在Manager管理器上暴露出来的方法。这是刻意设计的一个安全机制,用来防止你意外地请求类似models.User.objects.delete()的动作,而不慎删除了所有的条目。如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集,像下面这样:

    models.User.objects.all().delete()

    改:

    使用update()方法可以批量为QuerySet中所有的对象进行更新操作。

    models.User.objects.filter(name__contents="Alex").update(name="Eric")

    要注意的是update()方法会直接转换成一个SQL语句,并立刻批量执行。它不会运行模型的save()方法,或者产生pre_savepost_save信号

    2.5记录表的查询

    查询的API较多,所以放在最后,而且这里仅列出少量常用API

    方法                说明
    
    all()           # 获取所有对象
    filter(**kwargs)           # 根据条件过滤查询对象
    exclude(**kwargs)         # 排除满足条件的对象
    order_by(*fileld)         # 对查询集进行排序
    reverse()           # 反向排序
    values(*fileld)             # 返回一个特殊的的QuerySet,这个QuerySet中不是一个个models的实例化对象,而是根据*fileld查询的具体值的字典
    values_list(*fileld)       # 这个和values()类似,但是它返回的是元组,而不是字典
    distinct()         # 从返回的查询集中剔除重复记录
    
    # 注意上面的API返回的是QuerySet对象,下面的API不返回QuerySet对象
    
    get()      # 获取单个对象
    first()       # 获取查询到的第一个对象
    last()       # 获取查询到的最后一个对象
    count()      # 统计查询的QuerySet中对象个数
    exists()        # 判断QuerySet中是否有对象,有返回True,无返回Flase
    
    
    另:使用类似Python对列表进行切片的方法可以对QuerySet进行范围取值
    models.User.objects.all()[:5]      # 返回前5个对象
    models.User.objects.all()[5:10]    # 返回第6个到第10个对象
     # 不支持负索引!

    字段查询是指如何指定SQL WHERE子句的内容。它们用作QuerySet的filter(), exclude()和get()方法的关键字参数

    常用字段查询参数(双下滑线的模糊查询):

    参数                 说明
    
    contains       # 区分大小写的包含匹配
    icontains       # 不区分大小写的包含匹配
    in             # 在...中的匹配
    gt / gte            # 大于 / 大于等于
    lt / lte            # 小于 / 小于等于
    range            # 范围匹配
    date            # 日期匹配
    year / month / day          # 年 / 月 / 日    匹配
    startswith / istartswith      # 区分大小写/不区分大小写     以...开头匹配
    endswith / iendswith        # 区分大小写/不区分大小写     以...结尾匹配
    
    
    用法
    
    models.User.objects.filter(id__gt=5)
    models.User.objects.filter(id__range=[10,15])
    models.User.objects.filter(name__contains="Alex")
    models.User.objects.filter(name__icontains="ALEX")
    models.User.objects.filter(name__startswith="E")
    models.User.objects.filter(create_time__year=2016)
    

     

    终日不为以思,无益,不如学也
  • 相关阅读:
    MongoDB入门示例及介绍
    Oracle/PLSQL CURSOR FOR Loop
    JAVA写的文件分割与文件合并程序
    synchronized 解决死锁的问题 轉貼
    采用批处理命令对文件进行解压及采用SQLCMD进行数据库挂载
    chapter6作业
    chapter5作业
    chapter4作业
    Linuz系统管理 -----账号管理
    chapter02
  • 原文地址:https://www.cnblogs.com/lymlike/p/11547929.html
Copyright © 2011-2022 走看看