<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Python on LeoChu Space</title>
    <link>https://leochu.work/blog/tags/python/</link>
    <description>Recent content in Python on LeoChu Space</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 16 Mar 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://leochu.work/blog/tags/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ORM常用操作</title>
      <link>https://leochu.work/blog/tech/python/django/orm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sat, 16 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/orm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;h1 id=&#34;orm常用操作&#34;&gt;ORM常用操作&lt;/h1&gt;
&lt;p&gt;Django开发过程中对表(model)的增删改查是最常用的功能之一，本文介绍笔者在使用model 操作过程中遇到的一些操作。&lt;/p&gt;
&lt;h1 id=&#34;model-update常规用法&#34;&gt;model update常规用法&lt;/h1&gt;
&lt;p&gt;假如我们的表结构是这样的&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class User(models.Model):
    username = models.CharField(max_length=255, unique=True, verbose_name=&amp;#39;用户名&amp;#39;)
    is_active = models.BooleanField(default=False, verbose_name=&amp;#39;激活状态&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;那么我们修改用户名和状态可以使用如下两种方法：&lt;/p&gt;
&lt;p&gt;方法一：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;User.objects.filter(id=1).update(username=&amp;#39;nick&amp;#39;,is_active=True)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;方法二：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_t = User.objects.get(id=1)
_t.username=&amp;#39;nick&amp;#39;
_t.is_active=True
_t.save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;方法一适合更新一批数据，类似于mysql语句&lt;code&gt;update user set username=&#39;nick&#39; where id = 1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;方法二适合更新一条数据，也只能更新一条数据，当只有一条数据更新时推荐使用此方法，另外此方法还有一个好处，我们接着往下看&lt;/p&gt;
&lt;h1 id=&#34;具有auto_now属性字段的更新&#34;&gt;具有auto_now属性字段的更新&lt;/h1&gt;
&lt;p&gt;我们通常会给表添加三个默认字段&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自增ID，这个django已经默认加了，就像上边的建表语句，虽然只写了username和is_active两个字段，但表建好后也会有一个默认的自增id字段&lt;/li&gt;
&lt;li&gt;创建时间，用来标识这条记录的创建时间，具有&lt;code&gt;auto_now_add&lt;/code&gt;属性，创建记录时会自动填充当前时间到此字段&lt;/li&gt;
&lt;li&gt;修改时间，用来标识这条记录最后一次的修改时间，具有&lt;code&gt;auto_now&lt;/code&gt;属性，当记录发生变化时填充当前时间到此字段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就像下边这样的表结构&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class User(models.Model):
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=&amp;#39;创建时间&amp;#39;)
    update_time = models.DateTimeField(auto_now=True, verbose_name=&amp;#39;更新时间&amp;#39;)
    username = models.CharField(max_length=255, unique=True, verbose_name=&amp;#39;用户名&amp;#39;)
    is_active = models.BooleanField(default=False, verbose_name=&amp;#39;激活状态&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;当表有字段具有&lt;code&gt;auto_now&lt;/code&gt;属性且你希望他能自动更新时，必须使用上边方法二的更新，不然auto_now字段不会更新&lt;/strong&gt;，也就是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_t = User.objects.get(id=1)
_t.username=&amp;#39;nick&amp;#39;
_t.is_active=True
_t.save()
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;jsondict类型数据更新字段&#34;&gt;json/dict类型数据更新字段&lt;/h1&gt;
&lt;p&gt;目前主流的web开放方式都讲究前后端分离，分离之后前后端交互的数据格式大都用通用的json型，那么如何用最少的代码方便的更新json格式数据到数据库呢？同样可以使用如下两种方法：&lt;/p&gt;
&lt;p&gt;方法一：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;data = {&amp;#39;username&amp;#39;:&amp;#39;nick&amp;#39;,&amp;#39;is_active&amp;#39;:&amp;#39;0&amp;#39;}
User.objects.filter(id=1).update(**data)
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;同样这种方法不能自动更新具有&lt;code&gt;auto_now&lt;/code&gt;属性字段的值&lt;/li&gt;
&lt;li&gt;通常我们再变量前加一个星号(*)表示这个变量是元组/列表，加两个星号表示这个参数是字典&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;方法二：&lt;/p&gt;</description>
    </item>
    <item>
      <title>数据模型字段及属性详解</title>
      <link>https://leochu.work/blog/tech/python/django/%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%E5%AD%97%E6%AE%B5%E5%8F%8A%E5%B1%9E%E6%80%A7%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Sun, 24 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%E5%AD%97%E6%AE%B5%E5%8F%8A%E5%B1%9E%E6%80%A7%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;h1 id=&#34;数据模型字段及属性详解&#34;&gt;数据模型字段及属性详解&lt;/h1&gt;
&lt;p&gt;在设计数据模型的时候，我们需要根据不同的需求，设计不同的表和不同的字段。不同的字段也可以设置不同的参数。&lt;/p&gt;
&lt;p&gt;一个模型（model）就是一个单独的、确定的数据的信息源，包含了数据的字段和操作方法。Django是通过Model操作数据库，不管你数据库的类型是MySql或者Sqlite，Django它自动帮你生成相应数据库类型的SQL语句，所以不需要关注SQL语句和类型，对数据的操作Django帮我们自动完成。只要回写Model就可以了！&lt;/p&gt;
&lt;p&gt;django根据代码中定义的类来自动生成数据库表。我们写的类表示数据库的表，如果根据这个类创建的对象是数据库表里的一行数据，对象.id 对象.value是每一行里的数据。&lt;/p&gt;
&lt;p&gt;基本的原则如下：
每个模型在Django中的存在形式为一个Python类
每个模型都是django.db.models.Model的子类
模型里的每个类代表数据库中的一个表
模型的每个字段（属性）代表数据表的某一列
Django将自动为你生成数据库访问API&lt;/p&gt;
&lt;p&gt;Django这种操作数据库的方式，我们把它叫做：&lt;strong&gt;关系对象映射（Object Relational Mapping，简称ORM）。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们之前有在&lt;a href=&#34;https://www.django.cn/course/show-11.html&#34;&gt;管理后台与model模型&lt;/a&gt;这文章里简单的接触过。里面的models代码：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Category(models.Model):
    name = models.CharField(&amp;#39;分类&amp;#39;,max_length=100)
    
class Tags(models.Model):
    name = models.CharField(&amp;#39;标签&amp;#39;,max_length=100)
    
class Article(models.Model):
    title = models.CharField(&amp;#39;标题&amp;#39;,max_length=70)
    intro = models.TextField(&amp;#39;摘要&amp;#39;, max_length=200, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=&amp;#39;分类&amp;#39;, default=&amp;#39;1&amp;#39;)
    tags = models.ManyToManyField(Tags, blank=True)
    body = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=&amp;#39;作者&amp;#39;)
    created_time = models.DateTimeField(&amp;#39;发布时间&amp;#39;,auto_now_add=True)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;字段是模型中最重要的内容之一，也是唯一必须的部分。字段在Python中表现为一个类属性，体现了数据表中的一个列。Django不允许下面两种字段名：1、与Python关键字冲突。2、字段名中不能有两个以上下划线在一起，因为两个下划线是Django的查询语法。也不要使用clean、save、delete等Django内置的模型API名字，防止命名冲突。&lt;/p&gt;
&lt;p&gt;每一个字段都是一个类属性，每个类属性表示数据表中的一个列。上面那个models生成数据后，在数据库里是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;1.jpg&#34; loading=&#34;lazy&#34; src=&#34;https://www.django.cn/media/upimg/1_20180727113014_518.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;表名由Django自动生成，例如我们的Article类会自动生成为blog_Article，默认格式为“应用名称+下划线+小写类名”。如果你不指定主键，Django默认自动创建自增主键id。每个APP应用都有独立属于自己的模型，创建了APP之后，在使用它之前，你需要先在settings文件中的INSTALLED_APPS 处，注册models.py文件所在的app名称。看清楚了，是注册app，不是模型，也不是models.py。关于settings，我们前面也有讲解过，具体可查看文章：&lt;a href=&#34;https://www.django.cn/course/show-10.html&#34;&gt;全局配置settings详解&lt;/a&gt;。例如我们创建了名为blog的应用APP则在settings这样写：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;INSTALLED_APPS = [
#...
&amp;#39;blog&amp;#39;,  #我们要添加的应用名
#...
]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当你每次对模型进行增、删、修改时，我们都需要执行python manage.py makemigrations请务必执命令，然后再执行：python manage.py migrate，让操作实际应用到数据库上。&lt;/p&gt;</description>
    </item>
    <item>
      <title>分页</title>
      <link>https://leochu.work/blog/tech/python/django/%E5%88%86%E9%A1%B5/</link>
      <pubDate>Sun, 17 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E5%88%86%E9%A1%B5/</guid>
      <description>&lt;h1 id=&#34;分页-paginator&#34;&gt;分页 Paginator&lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;分页功能是几乎所有的网站上都需要提供的功能，当你要展示的条目比较多时，必须进行分页，不但能减小数据库读取数据压力，也有利于用户浏览。&lt;/p&gt;
&lt;p&gt;Django又很贴心的为我们提供了一个Paginator分页工具，但是不幸的是，这个工具功能差了点，不好添加CSS样式，所以前端的展示效果比较丑。如果你能力够，自己编写一个分页器，然后提交给Django官方吧，争取替代掉这个当前的分页器，我看好你哦！&lt;/p&gt;
&lt;p&gt;但不管怎么样，当前的Paginator分页器，还是要学一下用一下的。&lt;/p&gt;
&lt;h2 id=&#34;一实例展示&#34;&gt;一、实例展示&lt;/h2&gt;
&lt;p&gt;分页功能位于&lt;code&gt;django.core.paginator&lt;/code&gt;模块。&lt;/p&gt;
&lt;p&gt;向&lt;code&gt;Paginator&lt;/code&gt;提供包含一些对象的列表，以及你想每一页显示几条，比如每页5条、10条、20条、100条等等，它就会为你提供访问的一系列API方法，示例如下：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from django.core.paginator import Paginator
&amp;gt;&amp;gt;&amp;gt; objects = [&amp;#39;john&amp;#39;, &amp;#39;paul&amp;#39;, &amp;#39;george&amp;#39;, &amp;#39;ringo&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; p = Paginator(objects, 2)  # 对objects进行分页，虽然objects只是个字符串列表，但没关系，一样用。每页显示2条。

&amp;gt;&amp;gt;&amp;gt; p.count   # 对象个数
4
&amp;gt;&amp;gt;&amp;gt; p.num_pages  # 总共几页
2
&amp;gt;&amp;gt;&amp;gt; type(p.page_range)  # `&amp;lt;type &amp;#39;rangeiterator&amp;#39;&amp;gt;` in Python 2.
&amp;lt;class &amp;#39;range_iterator&amp;#39;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; p.page_range  # 分页范围
range(1, 3)

&amp;gt;&amp;gt;&amp;gt; page1 = p.page(1) # 获取第一页
&amp;gt;&amp;gt;&amp;gt; page1
&amp;lt;Page 1 of 2&amp;gt;
&amp;gt;&amp;gt;&amp;gt; page1.object_list # 获取第一页的对象
[&amp;#39;john&amp;#39;, &amp;#39;paul&amp;#39;]

&amp;gt;&amp;gt;&amp;gt; page2 = p.page(2)
&amp;gt;&amp;gt;&amp;gt; page2.object_list
[&amp;#39;george&amp;#39;, &amp;#39;ringo&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; page2.has_next()  # 判断是否有下一页
False
&amp;gt;&amp;gt;&amp;gt; page2.has_previous()# 判断是否有上一页
True
&amp;gt;&amp;gt;&amp;gt; page2.has_other_pages() # 判断是否有其它页
True
&amp;gt;&amp;gt;&amp;gt; page2.next_page_number() # 获取下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
&amp;gt;&amp;gt;&amp;gt; page2.previous_page_number() # 获取上一页的页码
1
&amp;gt;&amp;gt;&amp;gt; page2.start_index() # 从1开始计数的当前页的第一个对象
3
&amp;gt;&amp;gt;&amp;gt; page2.end_index() # 从1开始计数的当前页最后1个对象
4

&amp;gt;&amp;gt;&amp;gt; p.page(0)  # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
&amp;gt;&amp;gt;&amp;gt; p.page(3) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page contains no results
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;简单地说，使用Paginator分四步走：&lt;/p&gt;</description>
    </item>
    <item>
      <title>定制Admin管理后台</title>
      <link>https://leochu.work/blog/tech/python/django/%E5%AE%9A%E5%88%B6admin%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0/</link>
      <pubDate>Sun, 03 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E5%AE%9A%E5%88%B6admin%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;https://www.django.cn/course/show-11.html&#34;&gt;管理后台与model模型&lt;/a&gt;文章里，我们曾经有一个操作，就是在admin.py里注册blog应用，这样blog应用才会在后台显示出来，我们才能在后台对这个应用进行管理。这就是Django自带的后台管理的特色之一，它可以让我们快速便捷管理数据，后台管理可以在各个app的admin.py文件中进行控制。&lt;/p&gt;
&lt;p&gt;想要对APP应用进行管理，最基本的前提是要先在settings里对其进行注册，就是在INSTALLED_APPS里把APP名添加进去，更多的可以查看文章：&lt;a href=&#34;https://www.django.cn/course/show-10.html&#34;&gt;全局配置settings详解&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下面我们以一个blog应用来举例，向大家介绍一些常用的自定制admin的方法。如下为blog的models的Article表的内容:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Article(models.Model):
    title = models.CharField(&amp;#39;标题&amp;#39;, max_length=70)
    keywords = models.CharField(&amp;#39;文章关键词&amp;#39;, max_length=120, blank=True, null=True)
    excerpt = models.TextField(&amp;#39;摘要&amp;#39;, max_length=200, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=&amp;#39;分类&amp;#39;, blank=True, null=True)
    body = models.TextField(&amp;#39;内容&amp;#39;)
    user = models.ForeignKey(Userinfo, on_delete=models.CASCADE, verbose_name=&amp;#39;作者&amp;#39;)
    views = models.PositiveIntegerField(&amp;#39;阅读量&amp;#39;, default=0)
    top = models.IntegerField(choices=[(0, &amp;#39;否&amp;#39;), (1, &amp;#39;是&amp;#39;), ], default=0, verbose_name=&amp;#39;是否推荐&amp;#39;)
    created_time = models.DateTimeField(&amp;#39;发布时间&amp;#39;, auto_now_add=True)
    modified_time = models.DateTimeField(&amp;#39;修改时间&amp;#39;, auto_now=True)
    class Meta:
        verbose_name = &amp;#39;文章&amp;#39;verbose_name_plural = &amp;#39;文章&amp;#39;def __str__(self):
        return self.title
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一、管理后台注册需要管理的应用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;只有注册了，我们才能在管理后台看到这个APP应用，才能对其进行管理，这个注册有两种方式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、装饰器注册&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;from django.contrib import admin
from .models import Article
  
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display=(&amp;#39;id&amp;#39;, &amp;#39;category&amp;#39;, &amp;#39;title&amp;#39;, &amp;#39;user&amp;#39;,&amp;#39;views&amp;#39;,&amp;#39;created_time&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;2、注册参数&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
