【Django】掌握models.py模型文件的使用

news2024/12/23 20:10:31

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。


文章目录

  • 前言
  • 一、models类继承
    • (一)创建apps文件夹
    • (二)settings.py文件配置
    • (三)新建BaseModel
    • (四)项目中调用
  • 二、时间字段
    • (一)时间字段
    • (二)默认时间
    • (三)时间字段允许为空
  • 三、选择字段(枚举)
    • (一)选择的基础
    • (二)TextChoices枚举
    • (三)IntegerChoices枚举
    • (四)选择字段的序列化
  • 四、文件字段FileField
    • (一)系统默认路径
    • (二)自定义路径
    • (三)使用存储服务器
  • 五、外键字段
    • (一)外键的基本使用
    • (二)外键允许为空
    • (三)自定义中间表
  • 六、Django用户表扩展
    • (一)通过OneToOneField扩展用户表
    • (二)通过AbstractUser或AbstractBaseUser扩展用户表
      • 1.用户app下modles.py文件
      • 2.修改项目settings文件的AUTH_USER_MODEL 配置参数


前言

已经有很多人写过相关博客了,我为什么还要写一份呢?这个主要是因为很多文章写的还是很笼统,没法针对使用清晰的进行说明。本博客不是科普如何使用models的,重点关注日常开发中的使用情况,主要介绍类的继承、时间字段、选择字段、文件字段和外键字段。


一、models类继承

models类继承主要依赖Meta.abstract参数,以创建一个全局通用BaseModel为例介绍累的继承。

(一)创建apps文件夹

(二)settings.py文件配置

# 项目根目录
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE_DIR / "apps"))

(三)新建BaseModel

在app文件夹下新建db.py文件,内容如下:
在这里插入图片描述

from django.contrib.gis.db import models


class BaseModel(models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    is_delete = models.BooleanField(default=False, verbose_name="删除标记")

    class Meta:
        # 说明是一个抽象模型类,此句必须有,否则迁移会失败
        abstract = True

(四)项目中调用

from db import BaseModel
class CartItem(BaseModel):
	id = models.AutoField(primary_key=True)
	
    class Meta:
        verbose_name = '购物车'
        verbose_name_plural = '购物车'

二、时间字段

之前写过一篇关于python中如何使用时间的一篇博客《【Python】时间标准库处理》,当时就考虑到django在使用时,涉及到时间格式的转化和使用。

(一)时间字段

class BaseModel(models.Model):
    """模型抽象基类"""
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")

(二)默认时间

from django.utils import timezone
from db import BaseModel

class CartItem(BaseModel):
	id = models.AutoField(primary_key=True)
    create_time = models.DateTimeField('创建时间(BJ)', default=timezone.now, blank=True)
	
    class Meta:
        verbose_name = '购物车'
        verbose_name_plural = '购物车'

(三)时间字段允许为空

    transfer_time = models.DateTimeField('星地数传时间', null=True, blank=True, help_text='星地数传时间')

三、选择字段(枚举)

常用的选择字段是models.CharField,还可以使用models.IntegerField。下面我们看看都是如何使用。

(一)选择的基础

models.CharField是最常见的,也是使用最多的

from django.db import models

class Student(models.Model):
    FRESHMAN = "FR"
    SOPHOMORE = "SO"
    JUNIOR = "JR"
    SENIOR = "SR"
    GRADUATE = "GR"
    YEAR_IN_SCHOOL_CHOICES = {
        FRESHMAN: "Freshman",
        SOPHOMORE: "Sophomore",
        JUNIOR: "Junior",
        SENIOR: "Senior",
        GRADUATE: "Graduate",
    }
    year_in_school = models.CharField(
        max_length=2,
        choices=YEAR_IN_SCHOOL_CHOICES,
        default=FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in {self.JUNIOR, self.SENIOR}

(二)TextChoices枚举

from django.utils.translation import gettext_lazy as _


class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = "FR", _("Freshman")
        SOPHOMORE = "SO", _("Sophomore")
        JUNIOR = "JR", _("Junior")
        SENIOR = "SR", _("Senior")
        GRADUATE = "GR", _("Graduate")

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool,
        default=YearInSchool.FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in {
            self.YearInSchool.JUNIOR,
            self.YearInSchool.SENIOR,
        }

如果TextChoices枚举被多次使用,还可以抽象为一个单独的包,供django调用。

(三)IntegerChoices枚举

class Card(models.Model):
    class Suit(models.IntegerChoices):
        DIAMOND = 1
        SPADE = 2
        HEART = 3
        CLUB = 4

    suit = models.IntegerField(choices=Suit)

(四)选择字段的序列化

如果使用的是基础的选择方式,django提供了默认的序列化方法 get_year_in_school_dispaly()可供调用。如果选择了TextChoices或者IntegerChoices,需要自己写序列化方法。

TextChoices示例如下:

from django.utils.translation import gettext_lazy as _

class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = "FR", _("Freshman")
        SOPHOMORE = "SO", _("Sophomore")
        JUNIOR = "JR", _("Junior")
        SENIOR = "SR", _("Senior")
        GRADUATE = "GR", _("Graduate")

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool,
        default=YearInSchool.FRESHMAN,
    )
    def get_year_in_school_name(self):
        return YearInSchool(self.year_in_school).name
        
    def get_year_in_school_value(self):
        return YearInSchool(self.year_in_school).value
        
    def get_year_in_school_label(self):
        return YearInSchool(self.year_in_school).label
        

以上示例中的name是FRESHMAN ,value是"FR",label是_(“Freshman”),常用的方式为get_year_in_school_label。参考drf序列化

四、文件字段FileField

(一)系统默认路径

class MyModel(models.Model):
    # file will be uploaded to MEDIA_ROOT/uploads
    upload = models.FileField(upload_to="uploads/")
    # or...
    # file will be saved to MEDIA_ROOT/uploads/2015/01/30
    upload = models.FileField(upload_to="uploads/%Y/%m/%d/")

上述示例是系统默认方式,文件最终将被保存至 MEDIA_ROOT 路径下

(二)自定义路径

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return "user_{0}/{1}".format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)
类型描述
instance模型的实例,其中 FileField 定义。更具体地说,这是附加当前文件的特定实例。
filename最初提供给文件的文件名。在确定最终目的地路径时,可以考虑,也可以不考虑。

(三)使用存储服务器

需要制定storage参数,国内常用的是阿里云、腾讯云、华为云等厂商的存储服务,我们需要在settings.py文件中自定义DEFAULT_FILE_STORAGE 参数。比如django使用阿里云的oss存储需要用django-aliyun-oss2-storage库。

五、外键字段

(一)外键的基本使用

from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        "Manufacturer",
        on_delete=models.CASCADE,
    )

class Manufacturer(models.Model):
    # ...
    pass

(二)外键允许为空

class MissionData(models.Model):
    bill = models.ForeignKey(Bill, verbose_name='消费记录', on_delete=models.SET_NULL, null=True, blank=True)

(三)自定义中间表

六、Django用户表扩展

(一)通过OneToOneField扩展用户表

(二)通过AbstractUser或AbstractBaseUser扩展用户表

1.用户app下modles.py文件

class LoginUser(AbstractUser):
    """用户表"""
    uuid = models.UUIDField(default=uuid.uuid1, unique=True, editable=False)
    name = models.CharField(verbose_name='真实姓名', max_length=30, null=True, blank=True)
    phone = models.CharField(verbose_name='手机号', max_length=11, null=True, blank=True)
    roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Roles')

    class Meta:
        verbose_name = '系统用户'
        verbose_name_plural = '系统用户'
        app_label = 'users'

    def __str__(self):
        return self.username

2.修改项目settings文件的AUTH_USER_MODEL 配置参数

AUTH_USER_MODEL = 'users.LoginUser'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1019491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python连接mysql数据库报错pymysql.err.OperationalError

报错如下&#xff1a; 历史工程使用的是python3.6pymysqlmysql8.0 原因分析&#xff1a; 1、可能密码错误&#xff0c;通过navicat可以正常连接, 可排除 2、可能新版mysql默认使用的caching_sha2_password认证方式&#xff0c;换成mysql_native_password就可以 解决方法&am…

【今日话题】如何看待Unity收费一事,对标中小公司的从业者的该如何做

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

nowcoder NC30 缺失的第一个正整数

目录 题目描述&#xff1a; 分析&#xff1a; 完整代码&#xff1a; 题目链接&#xff1a; https://www.nowcoder.com/share/jump/819478881694767416272 题目描述&#xff1a; 给定一个无重复元素的整数数组nums&#xff0c;请你找出其中没有出现的最小的正整数 进阶&am…

常用电压基准芯片SC431BVSNT1G 应用及介绍

SC431BVSNT1G安森美深力科一款集成电路为三端子可编程并联调节二极管。这些单片IC电压参考作为低温系数齐纳工作可使用两个外部电阻器从Vref编程到36V。工作电流范围很宽&#xff0c;从40 a到100 mA典型的动态阻抗为0.22&#xff0c;2.5 V参考电压便于获得来自5.0 V逻辑电源的稳…

Python爆破shadow文件密码

原理 加密算法(明文&#xff0c;盐值) 密文 上面是shadow文件中密码的加密公式&#xff0c;我们可以用Python中的crypt()函数进行上述运算&#xff0c;如果得出的密文与原来的一致&#xff0c;说明密码爆破成功。 关于盐值和shadow文件的字段详解&#xff0c;请移步我的这篇博…

Vue-01:MVVM数据双向绑定与Vue的生命周期

一、Vue介绍 1.1 什么是Vue &#xff1f; Vue是一个渐进式的JavaScript框架&#xff0c;用于构建用户界面。"渐进式"意味着Vue的设计理念是逐步增强应用的功能和复杂性&#xff0c;而不是一次性地引入所有功能。这使得开发者可以根据项目需求选择性地使用Vue的不同特…

Rocketmq并发和顺序消费的失败重试机制

文章目录 问题并发消费触发时机客户端发起请求 CONSUMER_SEND_MSG_BACKBroker处理CONSUMER_SEND_MSG_BACK请求 顺序消费Q&A消费的时候是一批的消息, 如果其中某条消费失败了,是所有的消息都会被重试吗&#xff1f;用户可以自己控制重试次数、重试间隔时间吗?批量消费消息,…

Redis分布式锁的实现方式、实现原理

目录 一、分布式锁的重要性与挑战1.1 分布式系统中的并发问题竞态条件数据不一致死锁 二、分布式锁的基本原理与实现方式2.1 分布式锁的基本概念2.2 基于数据库的分布式锁原理与实现方式优缺点 2.3 基于缓存的分布式锁原理与实现方式优缺点 三、Redis分布式锁的实现与使用3.1 使…

elasticsearch19-数据同步

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

算法通关村第13关【黄金】| 数论问题

1.欧几里得算法 思路&#xff1a;欧几里得算法 【欧几里得演算法(辗转相除法)】 https://www.bilibili.com/video/BV19r4y127fu/?share_sourcecopy_web&vd_sourced124eda224bf54d0e3ab795c0b89dbb0 class Solution {public int findGCD(int[] nums) {int min Integer.MA…

001:vue3 实现自定义指令v-copy复制

文章目录 1. 实现效果2. vue3 注册全局自定义指令详解&#xff08;v-copy&#xff09;3. main.js 注册全局自定义指令&#xff0c;挂载到 vue 上4. 页面使用 1. 实现效果 2. vue3 注册全局自定义指令详解&#xff08;v-copy&#xff09; 在src中&#xff0c;新建 directive 文…

鸟哥的LInux私房菜 基础学习篇 第四版 学习笔记

第一章 目前被称为纯种的Unix指的是System V以及BSD这两套软件。 要实现多任务的环境&#xff0c;除了硬件&#xff08;主要是CPU&#xff09;需要能够具有多任务的特性外&#xff0c;操作系统也需要支持这个功能。 如果网络有问题时&#xff0c;去/var/log目录查日志。 第二…

基于Java的高校科研信息管理系统设计与实现(亮点:完整严谨的科研项目审批流程、多文件上传、多角色)

高校科研信息管理系统 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序&#xff08;小蔡coding&#xff09;2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 主要功能描述 五、系统实现5.1…

Kafka自带zookeeper---集群安装部署

kafka简介 kafka官网&#xff1a;http://kafka.apache.org/kafka下载页面&#xff1a;http://kafka.apache.org/downloadskafka配置快速入门&#xff1a;http://kafka.apache.org/quickstart 首先让我们看几个基本的消息系统术语&#xff1a; •Kafka将消息以topic为单位进行…

STM32的HAL库SPI操作(master 模式)-根据时序图配置SPI

SPI相关基础知识 SPI基本概念请自行百度&#xff0c;参考&#xff1a;百度百科SPI简介.我们讲重点和要注意的地方。 master模式下要关注的地方 接线一一对应 也就是说主控的MISO,MOSI,SCLK,[CSn]分别和设备的MISO,MOSI,SCLK,[CSn]一一对应相连&#xff0c;不交叉&#xff0…

Linux 本地Yearning SQL 审核平台远程访问

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…

二叉树的几个递归问题

我的主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言&#xff1a; 二叉树的递归是二叉树很重要的问题&#xff0c;几乎解决二叉树的问题都要使用递归&#xff0c;接下来我们将解决二叉树几个最基础的递归问题。 目录 前言&#xff1a; 二叉树的前序&#xff0c;中序&…

负载均衡原理及应用

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

JDK8源码阅读环境配置

说明 环境 jdk 版本&#xff1a;1.8.0_381 系统&#xff1a;macos 13.5.1 Intel 目的 学习 jdk8 源码&#xff0c;并能自定注释。 新建 java 工程 在 idea 中新建 java 工程&#xff0c;注意并非 maven 工程。如下图&#xff1a;完成后&#xff0c;如下图&#xff1a; 配置…

中外超市纷争“到家”13年 永辉盒马山姆谁也不服谁

59岁的侯毅&#xff0c;需要一次机会&#xff0c;向刘强东、向张勇&#xff0c;还有马云证明盒马的可能。 日前&#xff0c;盒马香港IPO意外“搁置”&#xff0c;无形之中给国内零售市场再次增添了一丝寒意。 近几年国内线下商超市场一片低气压&#xff0c;不续租、关店、亏损…