Django的orm操做数据库

<html> <head> <meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'> <title>Django的orm操做数据库</title></head> <body><h1>Django的orm操做数据库</h1> <p>django学习连接:<a href='https://www.cnblogs.com/clschao/articles/10526431.html' target='_blank' class='url'>https://www.cnblogs.com/clschao/articles/10526431.html</a></p> <p>单表操做学习连接:<a href='https://www.cnblogs.com/clschao/articles/10427807.html' target='_blank' class='url'>https://www.cnblogs.com/clschao/articles/10427807.html</a></p> <h2>about</h2> <blockquote><p>mvc或者mvc框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不须要依赖于特定的数据库,经过简单的配置就能够轻松更换数据库,这极大的减轻了开发人员的工做量,不须要面对因数据库变动而致使的无效劳动</p> <p>orm 是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)</p> <p>sqlalchemy,和他很像的,可是django的orm没有独立出来让别人使,虽然功能比sqlalchemy更强大,可是别人用不了</p> <p>类对象-----&gt;sql------&gt;pymysql-------&gt;mysql服务端-----&gt;磁盘,orm其实就是讲类对象的语法翻译成sql语句的一个引擎,明白orm是什么了,剩下的就是怎么使用orm,怎么来写类对象关系语句。</p> </blockquote> <pre><code class='language-mysql' lang='mysql'>建立表: CREATE TABLE employee( id int primary key auto_increment, name varchar(20), gender bit default 1, brithday data, department varchar(20), salary decimal(8,2) )html

sql中的表记录 #添加一条表记录 insert employee (name,gender,brithday,salary,department) values("alex",1,"1985-12-12",8000,"保洁部");python

#查询一条表记录: select * from employee where age=24;mysql

#跟新一条表记录: update employee set birthday="1989-10-24" where id=1;git

#删除一条表记录: delete from employee where name="alex" </code></pre>web

<pre><code class='language-python' lang='python'>from django.db import models #python类 class Employee(models.Model): id=models.AutoField(primary_key=True) #主键id在django中能够不用写默认生成 name=models.CharField(max_length=32) gender=models.Booleanfield() department=models.CharField(max_length=32) salary=models.DecimalField(max_digits=8,decimal_place=2) </code></pre>正则表达式

<p>知识复习</p> <p>mysql中bit数据类型</p> <p>Bit称为位数据类型,其数据有两种取值:0和1,长度为1位。在输入0之外的其余值时,系统均把它们当1看待。这种数据类型常做为逻辑变量使用,用来表示真、假或是、否等二值选择</p> <p>mysql中decimal数据类型</p> <p>decimal(a,b)</p> <p> <strong><em>参数说明:</em></strong></p> <p> a:指定小数点左边和右边一共的十进制数字的最大个数,最大精度为38.</p> <p> b:指定小数点右边能够存储的十进制数字的最大个数。默认小数位数是0.</p> <p>&nbsp;</p> <h2>单表操做</h2> <h3>建立模型</h3> <p><img src="https://img-blog.csdnimg.cn/20200111204753595.png"></img></p> <p>建立名为book的app,再book下的models.py中建立模型:</p> <pre><code class='language-python' lang='python'>from django.db import modelssql

class Book(models.Model): id=models.AutoField(parmary_key=True) #若是表里面没有写主键,表里面会自动生成一个自增主键字段,叫作id字段,orm要求每一个表里必需要写一个主键,若是不写默认生成 title=models.CharField(max_length=32) #和varchar(32)是同样的,32个字符 status=models.BooleanField() pud_date=models.DateField() #必须存这种字段“2018-12-12” price=models.Decimal(max_digits=8,decimal_places=2) #max_digits最大位数,decimal_places小数部分占多少位 pulish=models.CharField(max_length=32) </code></pre>数据库

<h3>settings配置</h3> <p>在建立完模型book的app,要首先在项目settings中配置book</p> <pre><code class='language-python' lang='python'>INSTALLED_APPS = [ &#39;django.contrib.admin&#39;, #这是django给你提供的一些特殊功能的配置(应用,只是我们看不到),也在应用这里给配置的,这些功能若是你注销了,那么咱们执行同步数据库指令以后,就不会生成那些django自带的表了。由于执行数据库同步语句的时候,django会找这里面全部的应用,找到他们的models来建立表 &#39;django.contrib.auth&#39;, &#39;django.contrib.contenttypes&#39;, &#39;django.contrib.sessions&#39;, &#39;django.contrib.messages&#39;, &#39;django.contrib.staticfiles&#39;, &quot;book&quot; #直接写app的名字也行,写&#39;app01.apps.App01Config&#39;也行 ] </code></pre> <p>若是要使用mysql数据库须要在settings中配置:</p> <pre><code class='language-python' lang='python'>DATABASES = { &#39;default&#39;: { &#39;ENGINE&#39;: &#39;django.db.backends.mysql&#39;, &#39;NAME&#39;:&#39;bms&#39;,      # 要链接的数据库,链接前须要建立好 &#39;USER&#39;:&#39;root&#39;,       # 链接数据库的用户名 &#39;PASSWORD&#39;:&#39;&#39;,       # 链接数据库的密码 &#39;HOST&#39;:&#39;127.0.0.1&#39;, # 链接主机,默认本级 &#39;PORT&#39;:3306     # 端口 默认3306 } } </code></pre> <details> <summary>app配置单独的数据库</summary> <pre><code> DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'bms',      # 要链接的数据库,链接前须要建立好 'USER':'root',       # 链接数据库的用户名 'PASSWORD':'',       # 链接数据库的密码 'HOST':'127.0.0.1', # 链接主机,默认本级 'PORT':3306     # 端口 默认3306 }, 'app01': { #能够为每一个app都配置本身的数据,而且数据库还能够指定别的,也就是不必定就是mysql,也能够指定sqlite等其余的数据库 'ENGINE': 'django.db.backends.mysql', 'NAME':'bms',      # 要链接的数据库,链接前须要建立好 'USER':'root',       # 链接数据库的用户名 'PASSWORD':'',       # 链接数据库的密码 'HOST':'127.0.0.1', # 链接主机,默认本级 'PORT':3306     # 端口 默认3306 } } </code></pre> </details> <p>注意看:</p> <p>NAME是数据库的名字,在mysql连接前该数据库必须已经建立,而上面的sqlite数据库下的db.sqlite3是项目自动建立USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动咱们的django项目前,咱们须要激活咱们的mysql。而后,启动项目,会报错:no module named MySQLdb。这是由于django默认你导入的驱动是MySQLdb,但是mysqldb对于py3有很大的问题,因此咱们须要的驱动是pymysql因此,咱们只须要找到项目文件夹下的—init—,在里面写入:</p> <pre><code class='language-python' lang='python'>import pymsql pymysql.install_as_MySQLdb() </code></pre> <p>最后经过两条指令数据库迁移指令便可在指定的数据库中建表:</p> <pre><code class='language-python' lang='python'>python manage.py.makemigrations #生成记录,每次修改了models里面的内容或者添加了新的app里面写了models里面的内容,都要执行这两条 python manage.py migrate #执行上面这个语句的记录来建立表,生成的表名字前面会自带应用的名字,例如你的book表在mysql里面叫作app01_book表 </code></pre> <p>同步执行原理:</p> <pre><code> 在执行 python manager.py magrations 时django 会在相应的 app 的migration文件夹下面生成 一个python脚本文件 在执行 python manager.py migrte 时 django才会生成数据库表,那么django是如何生成数据库表的呢, django是根据 migration下面的脚本文件来生成数据表的 每一个migration文件夹下面有多个脚本,那么django是如何知道该执行那个文件的呢,django有一张django-migrations表,表中记录了已经执行的脚本,那么表中没有的就是还没执行的脚本,则 执行migrate的时候就只执行表中没有记录的那些脚本。 有时在执行 migrate 的时候若是发现没有生成相应的表,能够看看在 django-migrations表中看看 脚本是否已经执行了, 能够删除 django-migrations 表中的记录 和 数据库中相应的 表 , 而后从新 执行 </code></pre> <h3>更多参数和字段</h3> <h4>字段</h4> <pre><code class='language-python' lang='python'>&lt;1&gt; CharField 字符串字段, 用于较短的字符串. CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所容许的最大字符数.django

<2> IntegerField #用于保存一个整数.json

<3> DecimalField 一个浮点数. 必须 提供两个参数:

参数    描述
    max_digits    总位数(不包括小数点和符号)
    decimal_places    小数位数
            举例来讲, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:
             
            models.DecimalField(..., max_digits=5, decimal_places=2)
            要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
             
            models.DecimalField(..., max_digits=17, decimal_places=10) #max_digits大于等于17就能存储百万以上的数了
            admin 用一个文本框(&lt;input type=&quot;text&quot;&gt;)表示该字段保存的数据.

<4> AutoField 一个 IntegerField, 添加记录时它会自动增加. 你一般不须要直接使用这个字段; 自定义一个主键:my_id=models.AutoField(primary_key=True) 若是你不指定主键的话,系统会自动添加一个主键字段到你的 model.

<5> BooleanField A true/false field. admin 用 checkbox 来表示此类字段.

<6> TextField 一个容量很大的文本字段. admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框).

<7> EmailField 一个带有检查Email合法性的 CharField,不接受 maxlength 参数.

<8> DateField 一个日期字段. 共有下列额外的可选参数: Argument 描述 auto_now 当对象被保存时(更新或者添加都行),自动将该字段的值设置为当前时间.一般用于表示 "last-modified" 时间戳. auto_now_add 当对象首次被建立时,自动将该字段的值设置为当前时间.一般用于表示对象建立时间. (仅仅在admin中有意义...)

<9> DateTimeField 一个日期时间字段. 相似 DateField 支持一样的附加选项.

<10> ImageField 相似 FileField, 不过要校验上传对象是不是一个合法图片.#它有两个可选参数:height_field和width_field, 若是提供这两个参数,则图片将按提供的高度和宽度规格保存.
<11> FileField 一个文件上传字段. 要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting, 该格式将被上载文件的 date/time 替换(so that uploaded files don't fill up the given directory). admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) .

注意:在一个 model 中使用 FileField 或 ImageField 须要如下步骤:
        (1)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
        (出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 做为该目录的公共 URL. 要确保该目录对
         WEB服务器用户账号是可写的.
        (2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
         使用 MEDIA_ROOT 的哪一个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
         出于习惯你必定很想使用 Django 提供的 get_&lt;#fieldname&gt;_url 函数.举例来讲,若是你的 ImageField
         叫做 mug_shot, 你就能够在模板中以 {{ object.#get_mug_shot_url }} 这样的方式获得图像的绝对路径.

<12> URLField 用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且 没有返回404响应). admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框)

<13> NullBooleanField 相似 BooleanField, 不过容许 NULL 做为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项 admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据.

<14> SlugField "Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们一般用于URLs 若你使用 Django 开发版本,你能够指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. #在 之前的 Django 版本,没有任何办法改变50 这个长度. 这暗示了 db_index=True. 它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate the slug, via JavaScript,in the object's admin form: models.SlugField (prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields.

<13> XMLField 一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径.

<14> FilePathField 可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的. 参数 描述 path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此获得可选项目. Example: "/home/images". match 可选参数. 一个正则表达式, 做为一个字符串, FilePathField 将使用它过滤文件名. 注意这个正则表达式只会应用到 base filename 而不是 路径全名. Example: "foo..txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif. recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的所有子目录. 这三个参数能够同时使用. match 仅应用于 base filename, 而不是路径全名. 那么,这个例子: FilePathField(path="/home/images", match="foo.", recursive=True) ...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif

<15> IPAddressField 一个字符串形式的 IP 地址, (i.e. "24.124.1.30"). <16> CommaSeparatedIntegerField 用于存放逗号分隔的整数值. 相似 CharField, 必需要有maxlength参数. </code></pre>

<h4>自定义字段</h4> <pre><code class='language-python' lang='python'>class APIModel(models.Model): &quot;&quot;&quot;接口表&quot;&quot;&quot; api_title = models.CharField(max_length=64,verbose_name=&quot;接口名称&quot;) api_desc = models.CharField(max_length=64,verbose_name=&quot;接口描述&quot;) api_start_time = models.DateField(verbose_name=&quot;接口开始时间&quot;) api_end_time = models.DateField(verbose_name=&quot;接口结束时间&quot;)

def __str__(self):
    return self.api_title

def xxoo(self):
    if self.casemodel_set.count():

        a = &quot;%s%%&quot; % (self.casemodel_set.filter(case_pass_status=1).count() / self.casemodel_set.count() * 100)
        return a
    else:
        return 0

</code></pre>

<p>&nbsp;</p> <h4>参数</h4> <pre><code class='language-python' lang='python'>(1)null

若是为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.

(1)blank

若是为True,该字段容许不填。默认为False。 要注意,这与 null 不一样。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。 若是一个字段的blank=True,表单的验证将容许该字段是空值。若是字段的blank=False,该字段就是必填的。

(2)default

字段的默认值。能够是一个值或者可调用对象。若是可调用 ,每有新对象被建立它都会被调用,若是你的字段没有设置能够为空,那么未来若是咱们后添加一个字段,这个字段就要给一个default值

(3)primary_key

若是为True,那么这个字段就是模型的主键。若是你没有指定任何一个字段的primary_key=True, Django 就会自动添加一个IntegerField字段作为主键,因此除非你想覆盖默认的主键行为, 不然不必设置任何一个字段的primary_key=True。

(4)unique

若是该值设置为 True, 这个数据字段的值在整张表中必须是惟一的

(5)choices 由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 若是设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>并且这个选择框的选项就是choices 中的选项。 (6)db_index   若是db_index=True 则表明着为此字段设置数据库索引。

DatetimeField、DateField、TimeField这个三个时间字段,均可以设置以下属性。

(7)auto_now_add 配置auto_now_add=True,建立数据记录的时候会把当前时间添加到数据库。

(8)auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间。 </code></pre>

<p>关于auto_now,你须要知道的事情</p> <pre><code>当须要更新时间的时候,咱们尽可能经过datetime模块来建立当前时间,并保存或者更新到数据库里面,看下面的分析: 假如咱们的表结构是这样的

class User(models.Model): username = models.CharField(max_length=255, unique=True, verbose_name='用户名') is_active = models.BooleanField(default=False, verbose_name='激活状态')

那么咱们修改用户名和状态可使用以下两种方法:

方法一:

User.objects.filter(id=1).update(username='nick',is_active=True)

方法二:

_t = User.objects.get(id=1) _t.username='nick' _t.is_active=True _t.save()

方法一适合更新一批数据,相似于mysql语句update user set username='nick' where id = 1

方法二适合更新一条数据,也只能更新一条数据,当只有一条数据更新时推荐使用此方法,另外此方法还有一个好处,咱们接着往下看

具备auto_now属性字段的更新 咱们一般会给表添加三个默认字段

  • 自增ID,这个django已经默认加了,就像上边的建表语句,虽然只写了username和is_active两个字段,但表建好后也会有一个默认的自增id字段
  • 建立时间,用来标识这条记录的建立时间,具备auto_now_add属性,建立记录时会自动填充当前时间到此字段
  • 修改时间,用来标识这条记录最后一次的修改时间,具备auto_now属性,当记录发生变化时填充当前时间到此字段

就像下边这样的表结构

class User(models.Model): create_time = models.DateTimeField(auto_now_add=True, verbose_name='建立时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') username = models.CharField(max_length=255, unique=True, verbose_name='用户名') is_active = models.BooleanField(default=False, verbose_name='激活状态')

当表有字段具备auto_now属性且你但愿他能自动更新时,必须使用上边方法二的更新,否则auto_now字段不会更新,也就是:

_t = User.objects.get(id=1) _t.username='nick' _t.is_active=True _t.save()

json/dict类型数据更新字段 目前主流的web开放方式都讲究先后端分离,分离以后先后端交互的数据格式大都用通用的jason型,那么如何用最少的代码方便的更新json格式数据到数据库呢?一样可使用以下两种方法:

方法一:

data = {'username':'nick','is_active':'0'} User.objects.filter(id=1).update(**data)

一样这种方法不能自动更新具备auto_now属性字段的值 一般咱们再变量前加一个星号(*)表示这个变量是元组/列表,加两个星号表示这个参数是字典 方法二:

data = {'username':'nick','is_active':'0'} _t = User.objects.get(id=1) _t.dict.update(**data) _t.save()

方法二和方法一一样没法自动更新auto_now字段的值 注意这里使用到了一个__dict__方法 方法三:

_t = User.objects.get(id=1) _t.role=Role.objects.get(id=3) _t.save()

#想让auto_now更新数据时自动更新时间,必须使用save方法来更新数据,因此很不方便,因此这个建立时自动添加时间或者更新时间的auto_now方法咱们最好就别用了,比较恶心,而且支持咱们本身来给这个字段更新时间: models.py: class Book(models.Model): name = models.CharField(max_length=32) date1 = models.DateTimeField(auto_now=True,null=True) date2 = models.DateTimeField(auto_now_add=True,null=True)

views.py: import datetime models.Book.objects.filter(id=1).update( name='chao', date1=datetime.datetime.now(), date2=datetime.datetime.now(), ) </code></pre>

<h2>添加表记录</h2> <p>在python中orm的对应关系有三种:</p> <p>类 --------&gt; 表</p> <p>类对象 --------&gt; 行(记录)</p> <p>类属性 -------------&gt; 表的字段(重点)</p> <p>首先想要操做表的增删改查,你须要导入这个表</p> <pre><code class='language-python' lang='python'>#好比在django的view视图中 from app01 import models

def add_book(request): """ 添加表记录 :param request:http请求信息""" models.Book(title='python',price=123,pub_date='2012-12-12',publish='人民出版社') #pub_date=datetime.datetime.now(),这个字段直接给日期时间类型的数据也是能够的 </code></pre>

<h5>方式一:(这种方式人用的比较少)</h5> <pre><code class='language-python' lang='python'>book_obj=Book(title=&quot;python葵花宝典&quot;,state=True,price=100,publish=&quot;苹果出版社&quot;,pub_date=&quot;2012-12-12&quot;) #实例化一个对象表示一行记录,时间日期若是只写日期的话,时间默认是00.00.00,注意日期写法必须是2012-12-12这种格式 book_obj.save() #就是pymysql的那个commit提交 </code></pre> <h5>方式二:(用的比较多)</h5> <pre><code class='language-python' lang='python'>create方法的返回值book_obj就是插入book表中的python规划宝典这本书籍记录对象 book_obj=Book.objects.create(title=&quot;python葵花宝典&quot;,state=True,price=100,publish=&quot;苹果出版社&quot;,pub_date=&quot;2012-12-12&quot;) #这个返回值就是那个new对象,新建立的记录对象 #若是是下面这种数据,记得post请求提交过来具备csrf_token的键值对要删除 data = request.POST.dict() del data[&quot;csrfmiddlewaretoken&quot;] models.Book.objects.create(**data) </code></pre> <p>实例演示:<a href='https://www.cnblogs.com/g15009428458/articles/12181331.html' target='_blank' class='url'>https://www.cnblogs.com/g15009428458/articles/12181331.html</a></p> <h5>方式三:批量插入</h5> <pre><code class='language-python' lang='python'>book_list = [] for i in range(10): bk_obj =models.Book( name=&quot;guo%s&quot;%i, addr=&quot;北京%s&quot;%i ) models.Book.objects.bulk_create(book_list) #批量插入,速度快 </code></pre> <p>update_or_create:有就跟新没有就建立,还有get_or_create,有就查询出来,没有就建立</p> <pre><code class='language-python' lang='python'>obj,created = models.UserToken.objects.update_or_create( user=user, # 查找筛选条件 defaults={ # 添加或者更新的数据       &quot;token&quot;:random_str,     } ) </code></pre> <h2>查询表记录</h2> <p>Book.object.all()获取全部的书籍</p> <pre><code>1 all() 查询全部结果,结果是queryset类型 2 filter(**kwargs): 它包含了与所给筛选条件的匹配对象,结果也是queryset类型 3 get(**kwargs): 返回与筛选条件匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个,若是符合条件的对象超过一个或者没有都会抛出错误捕获异常try 4 exclude(**kwargs): 排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操做,用这个返回的是queryset类型 5 order_by(*field): queryset类型的数据来调用,对插询结果排序,默认按照id升序排列,返回值仍是queryset类型 6 reverse(): queryset类型的数据来调用,对查询结果反向排序,返回值仍是queryset类型 7 count(): queryset类型的数据来调用,返回数据库中匹配查询(Queryset)的对象数量 8 first(): queryset类型的数据来调用,返回第一条数据,获得的都是model对象 9 last(): queryset类型数据来调用返回最后一条数据 10 exists(): queryset类型的数据来调用,若是Queryset包含数据,就返回True,不然返回False 11 values(*field): 用的比较多queryset类型的数据来调用,返回一个ValueQueryset,是一个字典,字典的键是字段,值是数据 12 values_list(*field): 它与values()类似,返回的是列表,对应的数据 13 distinct(): values和values_list获得的queryset类型的数据来调用,从返回结果中提出重复记录 </code></pre> <p>实例连接:<a href='https://www.cnblogs.com/g15009428458/articles/12182867.html' target='_blank' class='url'>https://www.cnblogs.com/g15009428458/articles/12182867.html</a></p> <h3>queryset方法大全</h3> <p>看博客:<a href='https://www.cnblogs.com/clschao/articles/10427807.html' target='_blank' class='url'>https://www.cnblogs.com/clschao/articles/10427807.html</a></p> <h3>关于distinct的用法和返回结果举例</h3> <pre><code class='language-python' lang='python'>#all_book = models.Book.objects.all().distinct() #这样写是表示记录中全部的字段重复,可是咱们知道有主键的存在,因此不可能全部字段数据都重复

#all_books = models.Book.objects.all().vaules_list('price').distinct() #只能用于values和values_list进行去重 #all_books = models.Book.objects.all().values_list('title','price').dictinct() #title和price两个同时重复才算一条重复记录 </code></pre>

<p>—str——魔法方法用法</p> <p>打印对象,让他显示一个可以看懂的值,&#39;<strong>str</strong>&#39;,models.py的数据表里面定义一个——str——方法就能够了</p> <pre><code class='language-python' lang='python'>#__str__方法的使用 class MyClass: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return self.name + &#39;&gt;&gt;&gt;&#39; + str(self.age)

a = MyClass('chao',18) b = MyClass('wc',20) print(a) print(b) </code></pre>

<p>models.py的——str——的写法:</p> <pre><code class='language-python' lang='python'>from django.db import mosels

class Book(models.Model) id= models.AutoField(primary_key=True) title= models.CharField(max_length=32) price= models.DecimalField(max_digit=8,decimal_places=2) pub_date= models.DateTimeField() #这个字段必须存这种格式“2020-02-12” pudlish= models.CharField(max_length=32) def str(self): return self.title #当咱们打印这个类的对象的时候,显是title值 </code></pre>

<h2>基于双下划线模糊查询</h2> <pre><code class='language-python' lang='python'>Book.objects.filter(price__in=[100,200,300]) #price值等于这三个里面的任意一个的对象 Book.objects.filter(price__gt=100) #大于,大于等因而price__gte=100,别写price&gt;100,这种参数不支持 Book.objects.filter(price__lt=100) Book.objects.filter(price__range=[100,200]) #sql的between and,大于等于100,小于等于200 Book.objects.filter(title__contains=&quot;python&quot;) #title值中包含python的 Book.objects.filter(title__icontains=&quot;python&quot;) #不区分大小写 Book.objects.filter(title__startswith=&quot;py&quot;) #以什么开头,istartswith 不区分大小写 Book.objects.filter(pub_date__year=2012) </code></pre> <p>日期查询实例</p> <pre><code class='language-python' lang='python'> # all_books = models.Book.objects.filter(pub_date__year=2012) #找2012年的全部书籍 # all_books = models.Book.objects.filter(pub_date__year__gt=2012)#找大于2012年的全部书籍 all_books = models.Book.objects.filter(pub_date__year=2019,pub_date__month=2)#找2019年月份的全部书籍,若是明明有结果,你却查不出结果,是由于mysql数据库的时区和我们django的时区不一样致使的,了解一下就好了,你须要作的就是将django中的settings配置文件里面的USE_TZ = True改成False,就能够查到结果了,之后这个值就改成False,并且就是由于我们用的mysql数据库才会有这个问题,其余数据库没有这个问题 </code></pre> <h2>删除表记录</h2> <p>delete()方法的调用者能够是一个model对象,也能够是一个queryset集合</p> <p>删除方法就是delete().它运行时当即删除对象而不返回任何值。例如:</p> <pre><code class='language-python' lang='python'>models_obj.delete() </code></pre> <p>你也能够一次性删除多个对象,每一个Queryset都有一个delete()方法,它一次性删除Queryset中全部的对象。例如,下面的代码将删除pub_date是2005年的Entry对象:</p> <pre><code class='language-python' lang='python'>Entry.objests.filter(pub_date_year=2005).delete() </code></pre> <p>在Django删除对象时,会模仿sql约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象</p> <pre><code class='language-python' lang='python'> </code></pre> <p>&nbsp;</p> </body> </html>

相关文章
相关标签/搜索