百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Django2.1常用模型字段详解,收藏随时查阅的精品笔记

toyiye 2024-09-16 06:09 3 浏览 0 评论

模型字段介绍

Django的模型其实是一个个类,不是对象,模型在应用polls文件夹下的models.py中定义。 你需要在项目设置文件settings.py中的 INSTALLED_APPS 设置中添加包含你 models.py 文件的模块的名字。

INSTALLED_APPS = [
 # 可以这样引用
 'polls',
]

字段说明:

字段是存储在模型中的数据,用来创建数据库表,他们分别来定义数据的类型/存储/关联等数据交互方式。

字段选项说明:

每个类型的字段的都会提供一些选项设置,用来增强或者设置字段的功能属性,其字段必须包含的选项将在下边展示的过程中显式的展示出来加以说明,可选选项将用 **options 代替。 max_length null blank default choices 等均是字段的 **options 选项。

标题字段 - CharField(max_length=50, **options)

max_length=50 用来限制字符串的长度50不是固定值可更改,通常用在标题类,因此为区分各类字符串字段,我将其称为标题字段,以下均是如此,仅作区分记忆之用,可能与官方文档称谓有差别,请知悉。

> 用法:first_name = models.CharField('姓名', max_length=50,)

内容字段 - TextField(**options)

> # 用 法:
content = models.TextField(
 '文章内容',
 max_length=1000,
 null=True,
 blank=True,
 default='默认值' )
  1. 括号内的所有属性均为选填项,这些可选为通用选项,可用于任何字段类型。
  2. 当设置null=True时,该字段为空,在数据库中该字段将被设置为NULL,仅在数据库层面。
  3. 避免在基于字符串的字段(如CharField和TextField)上使用null。 如果基于字符串的字段具有null = True,则表示它具有“无数据”的两个可能值:NULL和空字符串。 那么在大部分情况下为无数据提供两个空值则是多余的, Django约定是使用空字符串.
  4. 当blank=True时,该字段允许为空, 特别注意:该选项涉及表单验证,默认值为False,不允许为空。
  5. default为该字段的默认值,综3所述,当字符串字段设置blank=True时,建议设置default='',如下所示:
# 建议您这样使用:
content = models.TextField(blank=True, default='')

字段属性:choices 的用法

choices 的用法与前边几个用法大为不同,choices 接收的是一个可迭代的列表或元组(基本单位为二元组),如果指定了该参数,在实例化该模型时,该字段只能取选项列表中的值。

示例:

YEAR_IN_SCHOOL_CHOICES = (
 ('FR', 'Freshman'),
 ('SO', 'Sophomore'),
 ('JR', 'Junior'),
 ('SR', 'Senior'),
)
# 说明:每个二元组的第一个值会存储在数据库中,第二个值是用来显示的值,通俗讲就是人类可读的值。

用一个实例来说明他的具体用法:

from django.db import models
# 通常,最好在模型类中定义选项,并为每个值定义适当命名的常量:
class Student(models.Model):
 FRESHMAN = 'FR'
 SOPHOMORE = 'SO'
 JUNIOR = 'JR'
 SENIOR = 'SR'
 YEAR_IN_SCHOOL_CHOICES = (
 (FRESHMAN, 'Freshman'),
 (SOPHOMORE, 'Sophomore'),
 (JUNIOR, 'Junior'),
 (SENIOR, 'Senior'),
 )
 name = models.CharField(max_length=60)
 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)
 
> 备注:我们在模型类的最外边为choices的内部选项定义了常量,
> 然后将其存入到YEAR_IN_SCHOOL_CHOICES的二元组当中,这样方便我们在任何字段中调用其选项。

对于这个模型实例,要获取该字段二元组中相对应的第二个值,使用 get_FOO_display() 方法,其中 FOO 是字段的名称。例如:

>>> p = Student(name="某某高级中学", year_in_school="FR")
>>> p.save()
>>> p.year_in_school
'FR'
>>> p.get_year_in_school_display()
'Freshman'

还可以将其选项设置在一个命名组中:

每个组中的第一个元素为组名 第二个元素是一个可迭代的2元组,每个2元组包含一个存储在数据库中的值和一个人类可读的选项名称。

MEDIA_CHOICES = (
 ('Audio', (
 ('vinyl', 'Vinyl'),
 ('cd', 'CD'),
 )
 ),
 ('Video', (
 ('vhs', 'VHS Tape'),
 ('dvd', 'DVD'),
 )
 ),
 ('unknown', 'Unknown'),
)

时间字段 - DateField(**options) - or - DateTimeField( **options)

说明: 括号内属性均为选填项,默认拥有两种字段选项 auto_now=False 和 auto_now_add=False

## 当设置 auto_now=True ,那么在每次修改信息时都将自动保存为当前日期时间
> 用法1:pub_date = models.DateField('发布日期', auto_now=True)
> 用法2:pub_date = models.DateTimeField('发布日期', auto_now=True)
## 当设置 auto_now_add=True ,当你首次发布信息时自动保存你首次发布的时间。
## 之后修改信息时,即使是你用表单设置了该字段选项值,保存时也会忽略。
> 用法1:pub_date = models.DateField('发布日期', auto_now_add=True)
> 用法2:pub_date = models.DateTimeField('发布日期', auto_now_add=True)

备注: 当auto_now 与 auto_now_add 为 True 时,将导致字段自动具有editable=False (不可编辑修改) 和 blank=True 属性。

如果您想修改此字段请设置default而不是设置auto_now_add=True:

DateField: default=date.today - from datetime.date.today()
DateTimeField: default=timezone.now - from django.utils.timezone.now()

邮箱字段:EmailField(max_length=254, **options)

# max_length属性为必填项,与Charfield字段用法几乎一致
>> 用法:email = models.EmailField('邮箱地址', max_length=254)

十进制数字段:DecimalField(max_digits=None, decimal_places=None, **options)

# 一个固定精度的十进制数
dec = models.DecimalField(max_digits=5, decimal_places=2)
# max_digits 与 deciml_places 为必填项
max_digits=5 定义允许的最大位数,此数字必须大于或等于decimal_places。
decimal_places=2 定义数字的小数位数。

多对一字段:ForeignKey(to, on_delete, **options)

多对一的关系连接字段。有必须要的两个位置参数 to 和 on_delete 选项, to 表示与模型相关的类名,on_delete的一般用法是: on_delete=models.CASCADE 表示创建一种递归的多对一关系。

# 同应用中关联关系用法示例:
class Name(models.Model):
 # 此处代码省略...
 pass
class Age(models.Model):
 name = models.ForeignKey(
 Name,
 on_delete=models.CASCADE,
 verbose_name='姓名',)
## verbose_name选项是可选项,用来表示该字段名称,人类可读。
## 如果未设置,将使用字段的属性名称自动创建。
 age = models.CharField(max_length=2)
 
 def __str__(self):
 return self.name

如果你想把一个类的字段引用到其他模型,那么这个类所设置的这些字段将成为公共字段,这时你需要在你要引用的类中定义一个基类 Meta来抽象化这个类,然后将基类Meta的属性abstract 的值设为 True。 此时,抽象化的类将不能用作Django的普通模型,他不会生成数据表,也就不具有后台管理器,并且无法直接实例化。

如下例所示: 注意:从抽象类继承的字段可以用另一个字段或值覆盖,或者使用None删除。

from django.db import models
class CommonInfo(models.Model):
 name = models.CharField(max_length=100)
 age = models.PositiveIntegerField()
 class Meta:
 abstract = True
class Student(CommonInfo):
 home_group = models.CharField(max_length=5)

多对多关系字段:ManyToManyField(to, **options)

多对多的关系。 需要一个位置参数:与模型相关的类,它与ForeignKey完全相同,包括递归和惰性关系。

基本用法

from django.db import models
class Topping(models.Model):
 # ...
 pass
class Pizza(models.Model):
 # ...
 toppings = models.ManyToManyField(Topping)

一个人与他们所属的组之间存在多对多关系,因此您可以使用ManyToManyField来表示此关系。但是,您可能希望收集的成员资格有很多详细信息,例如此人加入该组的日期。对于这些情况,Django允许您指定将用于管理多对多关系的模型。然后,您可以在中间模型上添加额外的字段。中间模型与ManyToManyField相关联,使用through参数指向将充当中介的模型。如下例所示:

from django.db import models
class Person(models.Model):
 name = models.CharField(max_length=128)
 def __str__(self):
 return self.name
class Group(models.Model):
 name = models.CharField(max_length=128)
 # 您的中间模型必须包含一个 - 且只有一个 - 源模型的外键
 # 如果有两个以上的外键,则还必须指定through_fields,否则将引发验证错误。
 members = models.ManyToManyField(Person, through='Membership')
 def __str__(self):
 return self.name
class Membership(models.Model):
 person = models.ForeignKey(Person, on_delete=models.CASCADE)
 group = models.ForeignKey(Group, on_delete=models.CASCADE)
 date_joined = models.DateField()
 invite_reason = models.CharField(max_length=64)

对外键Membership的实例化操作:

>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

关联中间模型的多对多字段与普通的多对多字段不同,您不能使用add(),create() 或 set() 来创建关系,因此上创建此类关系的唯一方法是创建中间模型的实例。同样的原因remove()方法也被禁用,但是,可以使用clear()方法删除实例的所有多对多关系,如下例所示:

>>> # Beatles have broken up
>>> beatles.members.clear()
>>> # Note that this deletes the intermediate model instances
>>> Membership.objects.all()
<QuerySet []>

他的查询方法却与普通的多对多关系一样,可以使用多对多相关模型的属性进行查询:

# Find all the groups with a member whose name starts with 'Paul'
>>> Group.objects.filter(members__name__startswith='Paul')
<QuerySet [<Group: The Beatles>]>

在使用中间模型时,您还可以查询其属性:

# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
... group__name='The Beatles',
... membership__date_joined__gt=date(1961,1,1))
<QuerySet [<Person: Ringo Starr]>

如果您需要访问会员资格,可以直接查询会员资格模型:

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

访问相同信息的另一种方法是从Person对象查询多对多反向关系:

>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

仅在指定自定义中间模型具备两个外键时使用:ManyToManyField.through_fields。

from django.db import models
# Django通常会确定要使用哪个中间模型字段,以便自动建立多对多关系。
class Person(models.Model):
 name = models.CharField(max_length=50)
class Group(models.Model):
 name = models.CharField(max_length=128)
 members = models.ManyToManyField(
 Person,
 through='Membership',
 # 指定through_fields,关联起来的两个外键
 through_fields=('group', 'person'),
 )
class Membership(models.Model):
 group = models.ForeignKey(Group, on_delete=models.CASCADE)
 person = models.ForeignKey(Person, on_delete=models.CASCADE)
 inviter = models.ForeignKey(
 Person,
 on_delete=models.CASCADE,
 related_name="membership_invites",
 )
 invite_reason = models.CharField(max_length=64)

仅用于自定义ManyToManyFields。 考虑以下模型:

from django.db import models
class Person(models.Model):
 friends = models.ManyToManyField("self")

一对一关系字段:OneToOneField(to, on_delete, parent_link=False, **options)

一对一的关系字段,必须的两个位置参数to和on_delete选项,您可以像使用任何其他Field类型一样使用它:将其包含为模型的类属性。

class Name(models.Model):
 # 此处代码省略...
 pass
class Age(models.Model):
 name = models.OneToOneField(
 Name,
 on_delete=models.CASCADE,
 verbose_name='姓名',)
 age = models.CharField(max_length=2)
 
 def __str__(self):
 return self.age

文件上传字段:FileField(upload_to=None, max_length=100, **options)

此字段提供了一种设置上传目录和文件名的方式,可以通过两种方式设置。在这两种情况下,该值都被传递给 storage.save() 方法。不能设置主键primary_key.

如果指定字符串值,则可能包含strftime()格式,该格式将替换为文件上载的日期/时间(以便上载的文件不会填满给定目录)。 例如:

class MyModel(models.Model):
 # 文件将上传到 MEDIA_ROOT/uploads文件夹下
 upload = models.FileField(upload_to='uploads/')
 # 要么...
 # 文件将保存到 MEDIA_ROOT/uploads/2018/11/23
 upload = models.FileField(upload_to='uploads/%Y/%m/%d/')

在模型中使用FileField或ImageField (见下文)需要几个步骤:

  1. 在您的项目设置文件settings.py 中,需要将MEDIA_ROOT定义为您希望Django存储上载文件的目录的完整路径。 将MEDIA_URL定义为该目录的基本公共URL,确保Web服务器的用户帐户可以写入此目录,如下所示:。
# media_confige
MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
# 在项目url中配置
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# 模板中调用
 <img src="{{ MEDIA_URL }}{{ bookname.img }}" alt="图片调用" /> 

例如,假设您的MEDIA_ROOT设置为/home/media,upload_to设置为photos /%Y /%m /%d。 upload_to的'%Y /%m /%d'部分是strftime()格式; '%Y'是四位数年份,%m是两位数月份,%d是两位数日期。 如果您在2007年1月15日上传文件,它将保存在目录/home/media/photos/2007/01/15中。

  1. 将FileField或ImageField添加到模型中,定义upload_to选项以指定用于上载文件的MEDIA_ROOT子目录。
  2. 将存储在数据库中的所有内容都是文件的路径(相对于MEDIA_ROOT)。 您很可能希望使用Django提供的便捷网址属性。 例如,如果您的ImageField名为mug_shot,则可以使用{{object.mug_shot.url}}在模板中获取图像的绝对路径。

图片上传字段:ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)

从FileField继承所有属性和方法,但也验证上载的对象是有效图像。 除了可用于FileField的特殊属性之外,ImageField还有两个额外的可选参数:height_field 和 width_field,用来定义图片的高和宽。

ImageField实例在数据库中创建为varchar列,默认最大长度为100个字符。 与其他字段一样,您可以使用max_length参数更改最大长度。

此字段的默认表单窗口小部件是ClearableFileInput。

网址字段:URLField(max_length=200, **options)

该字段由URLValidator验证,max_length为可选选型,如果未指定,则默认值为200,此字段的默认表单窗口小部件是TextInput。

整数字段:IntegerField(**options)

此字段的默认表单窗口小部件是localize为False时的NumberInput,否则为TextInput。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码