柴少的博客 也许终将一事无成,却不能甘于平庸。

Django之ORM操作(六)

前面已经记录了django如何连接mysql数据库。

https://docs.djangoproject.com/en/2.0/topics/db/multi-db/    #如何联合多个数据库以及做数据库路由

一、模型字段参考(翻译官网)

官网链接:https://docs.djangoproject.com/en/2.0/ref/models/fields/

本文档包含Field的所有API参考,包括Django提供的字段选项和字段类型。

1.1 字段选项

以下参数适用于所有字段类型。 全部都是可选的。

null

Field.null

     如果为True,Django将在数据库中将空值存储为NULL。 默认值是False。

    避免在基于字符串的字段(如CharField和TextField)上使用null。 如果基于字符串的字段的值为空= True,则表示它有两个可能的值:“无数据”:NULL和空字符串。 在大多数情况下,“无数据”有两个可能的值是多余的,Django约定是使用空字符串,而不是NULL。 CharField同时具有unique = True和blank = True的一个例外是。 在这种情况下,当保存具有空白值的多个对象时,需要null = True来避免唯一的约束违规。

     对于基于字符串和非基于字符串的字段,如果您希望允许表单中的空值,则还需要设置blank = True,因为null参数仅影响数据库存储(请参见空白)。

注意:在使用Oracle数据库后端时,无论此属性如何,都将存储NULL值以表示空字符串。

如果要使用BooleanField接受null,请改为使用NullBooleanField。

blank

Field.blank

如果为True,则允许该字段为空。 默认值是False。

请注意,这与null不同。 null与纯数据库相关,而空白与验证相关。 如果一个字段的值为空,则表单验证将允许输入一个空值。 如果一个字段有空白= False,则该字段将是必需的。

choices

Field.choices

一个可迭代的(例如,一个列表或元组),其自身包含正好两个项目(例如[(A,B),(A,B)...])的迭代次数,以用作该字段的选择。 如果这是给定的,默认表单小部件将是一个选择框与这些选择而不是标准文本字段。

每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称。 例如:

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'),
    )
    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)

尽管您可以在模型类之外定义一个选择列表,然后引用它,但为模型类中的每个选项定义选项和名称会将所有这些信息与使用它的类相关联,并使得选择易于引用( 例如,Student.SOPHOMORE将在学生模型导入的任何地方工作)。

您还可以将可用选项收集到可用于组织目的的命名组中:

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

       每个元组中的第一个元素是要应用于该组的名称。第二个元素是2元组的迭代,每个2元组包含一个值和一个可读的名字作为选项。分组选项可以与单个列表中的未分组选项组合(例如本例中的未知选项)。

      对于每个设置了选项的模型字段,Django都会添加一个方法来检索字段当前值的人类可读名称。请参阅数据库API文档中的get_FOO_display()。

      请注意,选择可以是任何可迭代对象 - 不一定是列表或元组。这可以让你动态地构建选择。但是,如果你发现自己黑客的选择是动态的,那么最好使用带有ForeignKey的正确数据库表。选择意味着静态数据的变化不大,如果有的话。

      除非在默认情况下在字段上设置了空白= False,则包含“---------”的标签将与选择框一起呈现。要覆盖此行为,请将元组添加到包含None的选项;例如(无,'您的显示字符串')。或者,你可以使用空字符串而不是None,这是有道理的 - 比如在CharField上。

db_column

Field.db_column

用于此字段的数据库列的名称。 如果没有给出,Django将使用该字段的名称。

如果您的数据库列名是SQL保留字,或者包含Python变量名中不允许使用的字符 - 特别是连字符 - 这没关系。 Django在幕后引用列名和表名。

db_index

Field.db_index

如果为True,则会为此字段创建数据库索引。

db_tablespace

Field.db_tablespace

如果此字段已编入索引,则用于此字段索引的数据库表空间的名称。 默认值是项目的DEFAULT_INDEX_TABLESPACE设置(如果已设置)或模型的db_tablespace(如果有)。 如果后端不支持索引的表空间,则忽略此选项。

default

Field.default

字段的默认值。 这可以是一个值或一个可调用的对象。 如果可调用,则每次创建新对象时都会调用它。

缺省值不能是可变对象(模型实例,list,set等),因为对该对象的同一实例的引用将用作所有新模型实例中的默认值。 相反,将所需的默认值包装为可调用的。 例如,如果你想为JSONField指定一个默认dict,使用一个函数:

def contact_default():
    return {"email": "to1@example.com"}

contact_info = JSONField("ContactInfo", default=contact_default)

lambda不能用于默认字段选项,因为它们不能被迁移序列化。 请参阅该文档以了解其他注意事项。

对于像映射到模型实例的ForeignKey这样的字段,默认值应该是它们引用的字段的值(pk除非设置了to_field)而不是模型实例。

创建新模型实例时使用默认值,并且未为该字段提供值。 当该字段是主键时,当该字段设置为无时也使用默认值。

editable

Field.editable

如果为False,则该字段将不会显示在管理员或任何其他ModelForm中。 在模型验证过程中它们也被跳过。 默认值为True。

error_messages

Field.error_messages

error_messages参数允许您覆盖该字段将引发的默认消息。 传入一个字典,其中包含与要覆盖的错误消息相匹配的密钥。

错误消息键包括null,空白,无效,invalid_choice,唯一和unique_for_date。 为下面字段类型部分中的每个字段指定了其他错误消息键。

这些错误消息通常不会传播到表单。 请参阅关于模型的error_messages的注意事项。

help_text

Field.help_text

用窗体小部件显示额外的“帮助”文本。 即使您的字段未用于表单,对于文档也很有用。

请注意,该值在自动生成的表单中不是HTML转义的。 如果您愿意,可以在help_text中包含HTML。 例如:

help_text="Please use the following format: <em>YYYY-MM-DD</em>."

或者,您可以使用纯文本和django.utils.html.escape()来转义任何HTML特殊字符。 确保您避开可能来自不受信任的用户的任何帮助文本,以避免发生跨站点脚本攻击。

primary_key

Field.primary_key

如果为True,则此字段是模型的主键。

如果您没有为模型中的任何字段指定primary_key = True,Django将自动添加一个AutoField来保存主键,因此您不需要在任何字段上设置primary_key = True,除非您想覆盖 默认的主键行为。 有关更多信息,请参阅自动主键字段。

primary_key = True意味着null = False且unique = True。 一个对象只允许有一个主键。

主键字段是只读的。 如果您更改现有对象上主键的值并保存它,则会在旧对象旁边创建一个新对象。

unique

Field.unique

如果为True,则该字段在整个表格中必须是唯一的。

这是在数据库级和模型验证实施的。 如果您尝试在唯一字段中保存具有重复值的模型,则模型的save()方法会引发django.db.IntegrityError。

此选项在除ManyToManyField和OneToOneField之外的所有字段类型中都有效。

请注意,当unique为True时,您不需要指定db_index,因为unique意味着创建索引。

在Django 1.11中更改:在旧版本中,不能在FileField上使用unique = True。

unique_for_date

Field.unique_for_date

将其设置为DateField或DateTimeField的名称,以要求该字段对于日期字段的值是唯一的。

例如,如果您有一个字段标题unique_for_date =“pub_date”,那么Django将不允许输入两个具有相同标题和pub_date的记录。

请注意,如果您将其设置为指向DateTimeField,则只会考虑字段的日期部分。 另外,当USE_TZ为True时,检查将在对象保存时在当前时区执行。

这由Model.validate_unique()在模型验证期间实施,但不在数据库级。 如果任何unique_for_date约束涉及不属于ModelForm的字段(例如,如果其中一个字段在exclude中列出或具有editable = False),则Model.validate_unique()将跳过对该特定约束的验证。

unique_for_month

Field.unique_for_month

与unique_for_date一样,但要求该字段相对于该月份是唯一的。

unique_for_year

Field.unique_for_year

像unique_for_date和unique_for_month一样

verbose_name

Field.verbose_name

该字段的人类可读名称。 如果没有给出详细名称,Django将使用该字段的属性名称自动创建它,并将下划线转换为空格。 请参阅详细字段名称。

validators

Field.validators

要为此字段运行的验证程序列表。 有关更多信息,请参阅验证器文档。

注册和提取查找

Field实现查找注册API(https://docs.djangoproject.com/en/2.0/ref/models/lookups/#lookup-registration-api)。 该API可用于定制哪些查找可用于字段类,以及如何从字段中提取查找。

1.2 字段类型

AutoField

class AutoField(**options)[source]

一个IntegerField,根据可用的ID自动递增。 你通常不需要直接使用它; 如果不另外指定,主键字段将自动添加到您的模型中。 请参阅自动主键字段。

BigAutoField

class BigAutoField(**options)[source]

一个64位整数,与AutoField非常相似,只是保证适合1到9223372036854775807之间的数字。

BigIntegerField

class BigIntegerField(**options)[source]

一个64位整数,与IntegerField非常相似,只不过它保证适合从-9223372036854775808到9223372036854775807之间的数字。此字段的默认表单窗口小部件是TextInput。

BinaryField

class BinaryField(**options)[source]

用于存储原始二进制数据的字段。 它只支持字节分配。 请注意,该字段的功能有限。 例如,无法过滤BinaryField值上的查询集。 在ModelForm中也不可能包含BinaryField。

滥用BinaryField:尽管您可能会考虑在数据库中存储文件,但请考虑99%的情况下这是糟糕的设计。 该字段不是正确的静态文件处理的替代品。

BooleanField

class BooleanField(**options)[source]

True/False的领域。

该字段的默认表单窗口小部件是CheckboxInput。

如果您需要接受空值,则改为使用NullBooleanField。

当未定义Field.default时,BooleanField的默认值为None。

CharField

class CharField(max_length=None, **options)[source]

一个字符串字段,用于小到大尺寸的字符串。

对于大量的文本,请使用TextField。

该字段的默认表单窗口小部件是一个TextInput。

CharField有一个额外的必需参数:

CharField.max_length

字段的最大长度(以字符为单位)。 max_length在数据库级别和Django的验证中执行。

注意:如果您正在编写一个必须可移植到多个数据库后端的应用程序,则应该意识到某些后端对max_length存在限制。 有关详细信息,请参阅数据库后端注释(https://docs.djangoproject.com/en/2.0/ref/databases/)。

DateField

class DateField(auto_now=False, auto_now_add=False, **options)[source]

日期,由Python以datetime.date实例表示。 有一些额外的可选参数:

DateField.auto_now:

每次保存对象时自动将字段设置为现在。 用于“上次修改”的时间戳。 请注意,始终使用当前日期; 这不仅是您可以覆盖的默认值。

调用Model.save()时,该字段只会自动更新。 在以其他方式更新其他字段(如QuerySet.update())时,字段不会更新,但您可以在更新中为字段指定自定义值。

DateField.auto_now_add:

首次创建对象时,自动将字段设置为现在。 用于创建时间戳。 请注意,始终使用当前日期; 这不仅是您可以覆盖的默认值。 所以即使您在创建对象时为此字段设置了一个值,它也会被忽略。 如果您希望能够修改此字段,请设置以下字段而不是auto_now_add = True:

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

该字段的默认表单窗口小部件是一个TextInput。 管理员添加了JavaScript日历和“今日”的快捷方式。 包含一个额外的invalid_date错误消息密钥。

选项auto_now_add,auto_now和default是互斥的。 这些选项的任何组合都会导致错误。

注意:按照当前的实现,将auto_now或auto_now_add设置为True将导致该字段具有editable = False,并且空白= True设置。

注意:auto_now和auto_now_add选项将始终在创建或更新时使用默认时区中的日期。 如果你需要不同的东西,你可以考虑简单地使用你自己的可调用默认值或覆盖save()而不是使用auto_now或auto_now_add; 或者使用DateTimeField而不是DateField,并决定如何在显示时间处理从日期时间到日期的转换。

DateTimeField

class DateTimeField(auto_now=False, auto_now_add=False, **options)[source]

日期和时间,由Python以datetime.datetime实例表示。 采用与DateField相同的额外参数。

此字段的默认表单窗口小部件是单个TextInput。 管理员使用两个独立的TextInput小部件和JavaScript快捷键。

DecimalField

class DecimalField(max_digits=None, decimal_places=None, **options)[source]

一个固定精度的十进制数,由Python用十进制实例表示。 有两个必需的参数:

DecimalField.max_digits:

数字中允许的最大位数。 请注意,此数字必须大于或等于decimal_places。

DecimalField.decimal_places:

与号码一起存储的小数位数。

例如,要将分辨率为2位小数的数字存储到999,您可以使用:

models.DecimalField(..., max_digits=5, decimal_places=2)

并以10位小数的分辨率存储数量约10亿个:

models.DecimalField(..., max_digits=19, decimal_places=10)

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

注意:有关FloatField和DecimalField类之间差异的更多信息,请参阅FloatField与DecimalField。

DurationField

class DurationField(**options)[source]

用于存储时间段的字段 - 由timedelta在Python中建模。 在PostgreSQL上使用时,使用的数据类型是间隔时间,而在Oracle上,数据类型是INTERVAL DAY(9)TO SECOND(6)。 否则使用一个微秒的bigint。

注意:带有DurationField的算术在大多数情况下都适用。 但是,除了PostgreSQL以外的所有数据库,将DurationField的值与DateTimeField实例上的算术值进行比较将无法按预期进行。

EmailField

class EmailField(max_length=254, **options)[source]

一个CharField,用于检查该值是否为有效的电子邮件地址。 它使用EmailValidator来验证输入。

FileField

class FileField(upload_to=None, max_length=100, **options)[source]

文件上传字段。

注意:primary_key参数不受支持,如果使用,会引发错误。

有两个可选参数:

FileField.upload_to:

该属性提供了一种设置上传目录和文件名的方法,可以通过两种方式进行设置。 在这两种情况下,该值都传递给Storage.save()方法。

如果你指定一个字符串值,它可能包含strftime()格式,它将被文件上传的日期/时间所取代(这样上传的文件不会填满给定的目录)。 例如:

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/')

如果您使用的是默认的FileSystemStorage,则字符串值将被附加到您的MEDIA_ROOT路径中,以在本地文件系统上形成存储上传文件的位置。 如果您使用的是不同的存储,请检查存储的文档以了解它如何处理upload_to。

upload_to也可以是可调用的,例如函数。 这将被调用来获取上传路径,包括文件名。 这个可调用的方法必须接受两个参数,并返回一个Unix样式的路径(带正斜杠)传递给存储系统。 这两个论点是:

#参数         #说明
instance    FileField定义模型的一个实例。 更具体地说,这是当前文件被附加的特定实例。在大多数情况下,这个对象还没有被保存到数据库中,所以如果它使用默认的AutoField,它可能还没有它的主键字段的值。
filename    最初提供给该文件的文件名。 在确定最终目的地路径时,这可能会也可能不会被考虑到	

例子:

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)

FileField.storage:

存储对象,用于处理文件的存储和检索。 有关如何提供此对象的详细信息,请参阅管理文件。

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

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

  1. 在您的设置文件中,您需要将MEDIA_ROOT定义为您希望Django存储上传文件的目录的完整路径。 (对于性能,这些文件不存储在数据库中。)将MEDIA_URL定义为该目录的基本公用URL。 确保该目录可由Web服务器的用户帐户写入。

  2. 将FileField或ImageField添加到模型中,定义upload_to选项以指定用于上传文件的MEDIA_ROOT子目录。

  3. 所有将存储在数据库中的文件都是一个路径(相对于MEDIA_ROOT)。 你很可能想使用Django提供的便捷url属性。 例如,如果您的ImageField被称为mug_shot,则可以使用{{object.mug_shot.url}}在模板中获取图像的绝对路径。

例如,假设您的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目录中。

如果您想要检索上传文件的磁盘文件名或文件大小,可分别使用名称和大小属性; 有关可用属性和方法的更多信息,请参阅文件类参考和管理文件主题指南(https://docs.djangoproject.com/en/2.0/topics/files/)。

注意:该文件作为将模型保存在数据库中的一部分进行保存,因此在保存模型之后,不能依赖磁盘上使用的实际文件名。

      上传文件的相对URL可以使用url属性获取。在内部,它调用底层存储类的url()方法。

      请注意,无论何时处理上传的文件,都应密切关注您上传的文件以及它们的类型,以避免安全漏洞。验证所有上传的文件,以便确保文件是您认为的文件。例如,如果您盲目地让某人上传文件(如果没有进行验证)到Web服务器文档根目录中的目录中,则有人可以上传CGI或PHP脚本,并通过访问您网站上的URL来执行该脚本。不要容许。

     还要注意,即使是上传的HTML文件,由于它可以被浏览器执行(尽管不是由服务器执行),也可能造成与XSS或CSRF攻击等效的安全威胁。

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

FileField and FieldFile

class FieldFile[source]

当您访问模型上的FileField时,会为您提供FieldFile的实例作为访问基础文件的代理。

FieldFile的API反映了File的特性,只有一个关键区别:由该类包装的对象不一定是Python内置文件对象的包装。 相反,它是Storage.open()方法的结果的包装,可能是File对象,也可能是File API的自定义存储实现。

除了从File继承的API(例如read()和write())外,FieldFile还包含几个可用于与基础文件进行交互的方法:

警告:此类的两个方法save()和delete()默认保存关联的FieldFile的模型对象到数据库中。

FieldFile.name:

文件的名称,包括相关FileField的存储根目录的相对路径。

FieldFile.size:

底层Storage.size()方法的结果。

FieldFile.url:

通过调用基础Storage类的url()方法来访问文件相对URL的只读属性。

FieldFile.open(mode='rb')[source]

以指定模式打开或重新打开与此实例关联的文件。 与标准的Python open()方法不同,它不返回文件描述符。

由于底层文件在访问时隐式打开,因此可能不需要调用此方法,除非将指针重置为底层文件或更改模式。

FieldFile.close()[source]

行为与标准Python file.close()方法相似,并关闭与此实例关联的文件。

FieldFile.save(name, content, save=True)[source]

      此方法获取文件名和文件内容,并将它们传递给字段的存储类,然后将存储的文件与模型字段相关联。 如果要手动将文件数据与模型上的FileField实例相关联,则使用save()方法来保留该文件数据。

      接受两个必需的参数:名称是文件的名称,内容是包含文件内容的对象。 可选的save参数控制在与此字段关联的文件被更改后是否保存模型实例。 默认为True。

      请注意,content参数应该是django.core.files.File的一个实例,而不是Python的内置文件对象。 您可以像这样从现有的Python文件对象构建一个文件:

from django.core.files import File
# Open an existing file using Python's built-in open()
f = open('/path/to/hello.world')
myfile = File(f)

或者你可以像这样从Python字符串构造一个:

from django.core.files.base import ContentFile
myfile = ContentFile("hello world")

FieldFile.delete(save=True)[source]

删除与此实例关联的文件并清除该字段上的所有属性。 注意:如果在调用delete()时碰巧打开文件,此方法将关闭该文件。

可选的save参数控制在删除与该字段关联的文件后是否保存模型实例。 默认为True。

请注意,删除模型时,相关文件不会被删除。 如果您需要清理孤立的文件,则需要自行处理(例如,使用可以手动运行或计划通过例如cron定期运行的自定义管理命令)。

FilePathField

class FilePathField(path=None, match=None, recursive=False, max_length=100, **options)[source]

CharField的选项仅限于文件系统上某个目录中的文件名。 有三个特殊的论点,其中第一个是必需的:

FilePathField.path:

需要。 FilePathField应该从中选择的目录的绝对文件系统路径。 例如:“/home/images”。

FilePathField.match:

可选的。 FilePathField将用来过滤文件名的正则表达式,作为字符串。 请注意,正则表达式将应用于基本文件名,而不是完整路径。 例如:“foo.*\.txt$”,它将匹配一个名为foo23.txt但不是bar.txt或foo23.png的文件。

FilePathField.recursive:

可选的。 真或假。 默认值是False。 指定是否应该包含路径的所有子目录

FilePathField.allow_files:

可选的。 真或假。 默认值为True。 指定是否应该包含指定位置中的文件。 这个或allow_folders必须是True。

FilePathField.allow_folders:

可选的。 真或假。 默认值是False。 指定是否应该包含指定位置的文件夹。 这个或allow_files必须是True。


当然,这些论点可以一起使用。

一个潜在的问题是匹配适用于基本文件名,而不是完整路径。 所以,这个例子:

FilePathField(path="/home/images", match="foo.*", recursive=True)

...将匹配/home/images/foo.png,但不匹配/home/images/foo/bar.png,因为匹配适用于基本文件名(foo.png和bar.png)。

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

FloatField

class FloatField(**options)[source]

由浮点实例在Python中表示的浮点数。

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

FloatField与DecimalField:

FloatField类有时会与DecimalField类混合使用。 虽然它们都代表实数,但它们代表这些数字的方式不同。 FloatField在内部使用Python的float类型,而DecimalField使用Python的Decimal类型。 有关这两者之间区别的信息,请参阅Python的十进制模块文档。

ImageField

class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)[source]

继承FileField的所有属性和方法,但也会验证上传的对象是否为有效图像。

除了可用于FileField的特殊属性外,ImageField还具有高度和宽度属性。

为了便于查询这些属性,ImageField有两个额外的可选参数:

ImageField.height_field:

每次保存模型实例时将自动填充图像高度的模型字段的名称。

ImageField.width_field:

每次保存模型实例时将使用图像宽度自动填充的模型字段的名称。

需要Pillow library:

ImageField实例在数据库中创建为默认最大长度为100个字符的varchar列。 与其他字段一样,您可以使用max_length参数更改最大长度。该字段的默认表单窗口小部件是ClearableFileInput。

IntegerField

class IntegerField(**options)[source]

一个整数。 在Django支持的所有数据库中,值从-2147483648到2147483647都是安全的。 当localize为False或TextInput时,此字段的默认表单窗口小部件为NumberInput。

GenericIPAddressField

class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[source]

一个IPv4或IPv6地址,采用字符串格式(例如192.0.2.30或2a02:42fe :: 4)。 该字段的默认表单窗口小部件是一个TextInput。

IPv6地址规范化符合RFC 4291#section-2.2第2.2节的规定,包括使用该节第3段中建议的IPv4格式,如:: ffff:192.0.2.0。 例如,2001:0 :: 0:01将被标准化为2001 :: 1,:: ffff:0a0a:0a0a :: ffff:10.10.10.10。 所有字符都转换为小写字母。

GenericIPAddressField.protocol:

限制有效输入到指定的协议。 接受的值是'both'(默认),'IPv4'或'IPv6'。 匹配不区分大小写。

GenericIPAddressField.unpack_ipv4:

解压IPv4映射的地址,如:: ffff:192.0.2.1。 如果启用此选项,则该地址将解压到192.0.2.1。 默认是禁用的。 只能在协议设置为'both'时使用。

如果允许空白值,则必须允许空值,因为空白值存储为空值。

NullBooleanField

class NullBooleanField(**options)[source]

像一个BooleanField,但允许NULL作为其中一个选项。 使用它而不是使用null = True的BooleanField。 此字段的默认表单窗口小部件是NullBooleanSelect。

PositiveIntegerField

class PositiveIntegerField(**options)[source]

像IntegerField一样,但必须是正数或零(0)。 在Django支持的所有数据库中,值从0到2147483647都是安全的。 出于向后兼容性的原因,接受值0。

PositiveSmallIntegerField

class PositiveSmallIntegerField(**options)[source]

像PositiveIntegerField一样,但只允许在某个(数据库相关)点下的值。 在Django支持的所有数据库中,从0到32767的值都是安全的。

SlugField

class SlugField(max_length=50, **options)[source]

Slug是一个报纸术语。 一个Slug是一个短的标签,只包含字母,数字,下划线或连字符。 它们通常用于URL。

就像CharField一样,您可以指定max_length(也可以在该部分中读取有关数据库可移植性和max_length的注释)。 如果未指定max_length,则Django将使用默认长度50。意味着将Field.db_index设置为True。

根据其他值的值自动预先填充SlugField通常很有用。 您可以在管理中使用prepopulated_fields自动执行此操作。

SlugField.allow_unicode:

如果为True,则该字段除ASCII字母外还接受Unicode字母。 默认为False。

SmallIntegerField:

class SmallIntegerField(**options)[source]

像IntegerField一样,但只允许在某个(数据库相关)点下的值。 在Django支持的所有数据库中,-32768到32767的值都是安全的。

TextField

class TextField(**options)[source]

一个大文本字段。 该字段的默认表单窗口小部件是一个Textarea。
如果您指定了max_length属性,它将反映在自动生成的表单字段的Textarea小部件中。 但是它不是在模型或数据库级别实施的。 为此使用CharField。

TimeField

class TimeField(auto_now=False, auto_now_add=False, **options)[source]

一段时间,在Python中由datetime.time实例表示。 接受与DateField相同的自动填充选项。
该字段的默认表单窗口小部件是一个TextInput。 管理员添加了一些JavaScript快捷方式。

URLField

class URLField(max_length=200, **options)[source]

一个URL的CharField。该字段的默认表单窗口小部件是一个TextInput。
像所有CharField子类一样,URLField采用可选的max_length参数。 如果您不指定max_length,则使用默认值200。

UUIDField

class UUIDField(**options)[source]

用于存储通用唯一标识符的字段。 使用Python的UUID类。 在PostgreSQL上使用时,它将以uuid数据类型存储,否则以char(32)存储。
对于primary_key,通用唯一标识符是AutoField的一个很好的选择。 数据库不会为您生成UUID,因此建议使用默认值:

import uuid
from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # other fields

请注意,可调用(使用括号省略)传递给默认值,而不是UUID的实例。

1.3 关系方面

Django还定义了一组代表关系的字段。

ForeignKey

class ForeignKey(to, on_delete, **options)[source]

多对一的关系。 需要两个位置参数:与模型相关的类和on_delete选项。
要创建一个递归关系 - 一个与自身具有多对一关系的对象 - 请使用models.ForeignKey('self',on_delete = models.CASCADE)。
如果您需要在尚未定义的模型上创建关系,则可以使用模型的名称,而不是模型对象本身:

from django.db import models

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

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

当抽象模型被定义为具体模型的子类时,解析在抽象模型上定义的关系,并且与抽象模型的app_label不相关:

products/models.py:

from django.db import models

class AbstractCar(models.Model):
    manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)

    class Meta:
        abstract = True

production/models.py:

from django.db import models
from products.models import AbstractCar

class Manufacturer(models.Model):
    pass

class Car(AbstractCar):
    pass

# Car.manufacturer will point to `production.Manufacturer` here.

要引用另一个应用程序中定义的模型,可以使用完整的应用程序标签明确指定一个模型。 例如,如果上面的Manufacturer模型是在另一个称为production的应用程序中定义的,则需要使用:

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

当解决两个应用程序之间的循环导入依赖关系时,这种称为懒惰关系的引用可能很有用。
数据库索引是在ForeignKey上自动创建的。 您可以通过将db_index设置为False来禁用此功能。 如果要为一致性而不是联接创建外键,或者要创建替代索引(如部分索引或多列索引),则可能需要避免索引的开销。

数据库表示:

在幕后,Django将“_id”附加到字段名称以创建其数据库列名称。 在上例中,Car模型的数据库表将有一个manufacturer_id列。 (你可以通过指定db_column来明确地改变它)。但是,除非你编写自定义SQL,否则你的代码不应该处理数据库的列名。 您将始终处理模型对象的字段名称。

参数:

ForeignKey接受定义关系如何工作的细节。
ForeignKey.on_delete
当由ForeignKey引用的对象被删除时,Django将模拟由on_delete参数指定的SQL约束的行为。 例如,如果您有一个可以为空的ForeignKey,并且您希望在删除引用的对象时将其设置为null:

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

on_delete的可能值可在django.db.models中找到:

CASCADE[source]:

级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。

PROTECT[source]:

通过引发ProtectedError(django.db.IntegrityError的子类)来防止删除引用的对象。

SET_NULL[source]:

设置ForeignKey为空; 这只有在null为真时才可能。

SET_DEFAULT[source]:

将ForeignKey设置为其默认值; 必须设置ForeignKey的默认值。

SET()[source]:

将ForeignKey设置为传递给SET()的值,或者如果传递了可调用对象,则调用它的结果。 在大多数情况下,为了避免在导入models.py时执行查询,必须传递可调用对象:

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET(get_sentinel_user),
    )

DO_NOTHING[source]:

不采取行动。 如果数据库后端强制执行参照完整性,则会导致IntegrityError,除非您手动将SQL ON DELETE约束添加到数据库字段。

ForeignKey.limit_choices_to:

当此字段使用ModelForm或admin(默认情况下,查询集中的所有对象可供选择)呈现时,为此字段的可用选项设置限制。 可以使用字典,Q对象或返回字典或Q对象的可调用对象。
例如:

staff_member = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    limit_choices_to={'is_staff': True},
)

使ModelForm上的相应字段仅列出具有is_staff = True的用户。 这可能对Django管理员有帮助。
可调用表单可以是有用的,例如,当与Python日期时间模块结合使用时,可以按日期范围限制选择。 例如:

def limit_pub_date_choices():
    return {'pub_date__lte': datetime.date.utcnow()}

limit_choices_to = limit_pub_date_choices

如果limit_choices_to为或返回Q对象,这对于复杂查询很有用,那么只有在该模型的ModelAdmin的raw_id_fields中未列出该字段时,它才会对admin中可用的选择产生影响。
注意:
如果可调用函数用于limit_choices_to,则每次实例化新表单时都会调用它。 它也可能在模型验证时被调用,例如通过管理命令或管理员。 admin构造查询集以多次验证其在各种边界情况下的表单输入,因此可能会多次调用您的可调用对象。

ForeignKey.related_name:

从相关对象返回到这个关系的名称。 它也是related_query_name(用于来自目标模型的反向过滤器名称的名称)的默认值。 有关完整的解释和示例,请参阅相关的对象文档。 请注意,在定义关系抽象模型时,您必须设置此值; 当你这样做时,一些特殊的语法是可用的。
如果您希望Django不要创建向后关系,请将related_name设置为'+'或将其以'+'结尾。 例如,这将确保用户模型不会与此模型有倒退关系:

user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    related_name='+',
)

ForeignKey.related_query_name:

用于来自目标模型的反向过滤器名称的名称。 如果设置,它默认为related_name或default_related_name的值,否则默认为模型的名称:

# Declare the ForeignKey with related_query_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",
    )
    name = models.CharField(max_length=255)

# That's now the name of the reverse filter
Article.objects.filter(tag__name="important")

像related_name一样,related_query_name支持通过一些特殊语法的应用程序标签和类插值。

ForeignKey.to_field:

关系所在的相关对象上的字段。 默认情况下,Django使用相关对象的主键。 如果您引用不同的字段,则该字段必须具有unique=True。

ForeignKey.db_constraint:

控制是否应在数据库中为该外键创建约束。 默认值为True,这几乎可以肯定你想要的; 将其设置为False可能对数据完整性非常不利。 也就是说,以下是您可能需要执行此操作的一些场景:
您的遗留数据无效。你正在分解你的数据库。如果设置为False,则访问不存在的相关对象将引发其DoesNotExist异常。

ForeignKey.swappable:

如果此ForeignKey指向可交换模型,则控制迁移框架的反应。 如果它是True - 默认 - 那么如果ForeignKey指向一个与settings.AUTH_USER_MODEL(或另一个可交换模型设置)的当前值相匹配的模型,则该关系将使用对设置的引用存储在迁移中,而不是 该模型直接。
如果您确定模型应始终指向交换模型,则只希望将其重写为False - 例如,如果它是专门为您的自定义用户模型设计的配置文件模型。
将它设置为False并不意味着即使它被交换出来也可以引用可交换模型 - False意味着使用此ForeignKey进行的迁移将始终引用您指定的确切模型(因此如果用户尝试运行它将会失败 例如,您不支持的用户模型)。
如果有疑问,请将其保留为默认值True。

ManyToManyField

class ManyToManyField(to, **options)[source]

多对多的关系。 需要一个位置参数:与模型相关的类,其工作方式与ForeignKey完全相同,包括递归和惰性关系。
可以使用字段的RelatedManager添加,删除或创建相关对象。

数据库表示:
在幕后,Django创建一个中间连接表来表示多对多关系。 默认情况下,该表名是使用多对多字段的名称和包含它的模型的表的名称生成的。 由于某些数据库不支持超过一定长度的表名,因此这些表名将自动截断为64个字符,并且将使用唯一性散列。 这意味着你可能会看到像author_books_9cdf4这样的表名; 这是非常正常的。 您可以使用db_table选项手动提供连接表的名称。

参数:

ManyToManyField接受一组额外的参数 - 所有可选 - 控制关系如何运作。
ManyToManyField.related_name:与ForeignKey.related_name相同。
ManyToManyField.related_query_name : 与ForeignKey.related_query_name相同。
ManyToManyField.limit_choices_to:与ForeignKey.limit_choices_to相同。
在具有使用through参数指定的自定义中间表的ManyToManyField上使用时,limit_choices_to不起作用。

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

from django.db import models

class Person(models.Model):
    friends = models.ManyToManyField("self")

当Django处理这个模型时,它会识别它自己有一个ManyToManyField,因此它不会将Person_set属性添加到Person类中。 相反,ManyToManyField被认为是对称的 - 也就是说,如果我是你的朋友,那么你就是我的朋友。
如果你不想在与自身的多对多关系中对称,则将对称设置为False。 这将迫使Django为反向关系添加描述符,允许ManyToManyField关系不对称。

ManyToManyField.through:
Django会自动生成一个表来管理多对多的关系。 但是,如果您想手动指定中间表,则可以使用through选项来指定表示要使用的中间表的Django模型。
此选项最常见的用途是当您想要将多余数据与多对多关系关联时。
如果您没有指定显式贯穿模型,则仍然存在隐式贯穿模型类,您可以使用它直接访问创建的表以保存关联。 它有三个领域来链接模型。
如果源模型和目标模型不同,则会生成以下字段:

id:关系的主键。
<containing_model> _id:声明ManyToManyField的模型的ID。
<other_model> _id:ManyToManyField指向的模型的ID。
如果ManyToManyField指向和来自同一模型,则会生成以下字段:
id:关系的主键。
from_ <model> _id:指向模型的实例的id(即源实例)。
to_ <model> _id:关系指向的实例的id(即目标模型实例)。

该类可用于查询给定模型实例的关联记录,如普通模型。

ManyToManyField.through_fields:

仅在指定自定义中介模型时使用。 Django通常会确定要使用中间模型的哪些字段以自动建立多对多关系。 但是,请考虑以下型号:

from django.db import models

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=('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)

成员对Person(person和inviter)有两个外键,这使关系不明确,Django无法知道要使用哪一个。在这种情况下,您必须明确指定Django应该使用through_fields使用哪些外键,如上例所示。
through_fields接受一个2元组('field1','field2'),其中field1是定义ManyToManyField的模型外键的名称(本例中为group),field2是外键的名称目标模型(在这种情况下为人)。
如果在中介模型上有多个外键用于参与多对多关系的任何模型(或甚至两个模型),则必须指定through_fields。这也适用于使用中介模型时的递归关系,并且模型中有两个以上的外键,或者您想明确指定哪两个Django应该使用。
使用中间模型的递归关系总是被定义为非对称 - 也就是说,对称=假 - 因此,存在“源”和“目标”的概念。在这种情况下,'field1'将被视为关系的“源”,'field2'将被视为“目标”。

ManyToManyField.db_table:
用于存储多对多数据的表的名称。 如果没有提供,Django将根据以下名称采用默认名称:定义关系的模型表和字段本身的名称。
ManyToManyField.db_constraint:
控制是否应在数据库中为中间表中的外键创建约束。 默认值为True,这几乎可以肯定你想要的; 将其设置为False可能对数据完整性非常不利。

ManyToManyField.swappable:
如果此ManyToManyField指向可交换模型,则控制迁移框架的反应。 如果它是True - 默认值 - 那么如果ManyToManyField指向一个与settings.AUTH_USER_MODEL(或另一个可交换模型设置)的当前值匹配的模型,则该关系将使用对设置的引用存储在迁移中,而不是 该模型直接。
如果您确定模型应始终指向交换模型,则只希望将其重写为False - 例如,如果它是专门为您的自定义用户模型设计的配置文件模型。
如果有疑问,请将其保留为默认值True。
ManyToManyField不支持验证器。由于无法在数据库级别要求关系,因此null不起作用。

OneToOneField

class OneToOneField(to, on_delete, parent_link=False, **options)[source]

一对一的关系。 从概念上讲,这与具有unique = True的ForeignKey类似,但关系的“反向”侧将直接返回单个对象。
作为以某种方式“扩展”另一个模型的模型的主键,这是最有用的; 例如,多表继承通过从子模型向父模型添加隐式一对一关系来实现。
需要一个位置参数:模型将与之相关的类。 这与其为ForeignKey完全相同,包括所有关于递归和惰性关系的选项。
如果您没有为OneToOneField指定related_name参数,那么Django将使用当前模型的小写名称作为默认值。
用下面的例子:

from django.conf import settings
from django.db import models

class MySpecialUser(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    supervisor = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='supervisor_of',
    )

您生成的用户模型将具有以下属性:

>>> user = User.objects.get(pk=1)
>>> hasattr(user, 'myspecialuser')
True
>>> hasattr(user, 'supervisor_of')
True

如果相关表中的条目不存在,则在访问逆向关系时会引发DoesNotExist异常。 例如,如果用户没有由MySpecialUser指定的主管人员:

>>> user.supervisor_of
Traceback (most recent call last):
    ...
DoesNotExist: User matching query does not exist.

此外,OneToOneField接受ForeignKey接受的所有额外参数,并加上一个额外的参数:
OneToOneField.parent_link:
当为True且用于从另一个具体模型继承的模型中时,表示该字段应该用作返回父类的链接,而不是通常通过子类隐式创建的额外OneToOneField。
查看OneToOneField的使用示例的一对一关系。

二、django对数据库增删改查的例子

2.1 创建表和字段的例子

cmdb目录下models.py:

from django.db import models
# Create your models here.
class UserInfo(models.Model): #继承models.Model,必须继承,定义了一个UserInfo类,创建的表名称也会为cmdb_userinfo
     #id,自增,主键,隐藏的,如果不加也自动加上这列   #id是隐藏的会自己添加的字段
     #创建用户名列,字符串类型,指定长度
     username = models.CharField(max_length=32)
     password = models.CharField(max_length=64)

python manage.py makemigrations

python manage.py migrate

image.png

#随着修改,这里会产生新的文件,主要是用来记录和差异对比

image.png

#其他的表都是django的。

image.png

2.2 数据库增加字段操作

主站目录下的urls.py:

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from cmdb import views as cviews   #这种设置可以应付多app,不同app下的views可以做不同的别名区分

urlpatterns = [
    path('admin/', admin.site.urls),
    url('orm',cviews.orm),
]

cmdb目录下的views.py:

from django.shortcuts import render,HttpResponse
from cmdb import models   ##引入cmdb下的models

def orm(request):   #只要网页刷一下下面的orm就会执行下面的增加字段的操作
    models.UserInfo.objects.create(username='root',password='123')
    #这是给UserInfo类,也就是给cmdb_userinfo表增加字段操作,推荐使用这种
    return HttpResponse('orm')
    
    #dic = {'username':'eric','password':'666'}    #这是一种变种
        #models.UserInfo.objects.create(**dic)

        #obj = models.UserInfo(username='alex',password='123')  这是另外一种方式
        #obj.save()

image.png

image.png

2.3 基本的查询操作

result = models.UserInfo.objects.filter(username='test',password='123456') #这相当于双重条件匹配
#result = models.UserInfo.objects.filter(username='root') #过滤查找用户名为root的列
#result = models.UserInfo.objects.all() #all()查找所有
#result返回的是QuerySet类型,是django提供的,可以理解为一个[]列表
#[obj(id.username,password),obj(id.username,password),obj(id.username,password)]
for row in result:  #result可以是多列,所以要写for循环,
    print (row.id,row.username,row.password)
# print(result)

2.4 基本的删除操作:

#models.UserInfo.objects.all().delete() #删除所有字段
models.UserInfo.objects.filter(username='eric').delete() #基于什么条件删除
return  HttpResponse('orm')

2.5 基本的更新操作:

#models.UserInfo.objects.all().update(password="wokaokao") #所有的进行更新
models.UserInfo.objects.filter(id='1').update(password='123456') #根据条件更新

image.png

2.6 数据库表修改

增加列操作:

models.py里面的配置:

from django.db import models

# Create your models here.
class UserInfo(models.Model):
     username = models.CharField(max_length=32)
     password = models.CharField(max_length=64)
     email = models.CharField(max_length=64)  #后加入此列
     gender = models.CharField(max_length=64,null=True) #后加入此列,null=True,允许为空
#email = models.EmailField(max_length=64)  #注释掉就代表去除这一列,EmailField在admin管理的时候,提交的时候检查是否是制定格式。

特殊的是:

uid = models.AutoField(primary_key=True) #AutoField是自增的,要加上primary_key=True
 
字段的参数:
null               -> db是否可以为空
default            -> 默认值
primary_key        -> 主键
db_column          -> 列名
db_index           -> 索引
unique      -> 唯一索引
unique_for_date    -> 只对时间做索引
unique_for_month  -只对月份做索引
unique_for_year  -->只对年份做索引
auto_now           -> 创建时,自动生成时间
auto_now_add       -> 更新时,自动更新为当前时间

# obj = UserGroup.objects.filter(id=1).update(caption='CEO')
# obj = UserGroup.objects.filter(id=1).first()
# obj.caption = "CEO"
# obj.save()
#下面这些都是django-admin的: 
choices     -> django admin中显示下拉框,避免连表查询
blank             -> django admin是否可以为空
verbose_name      -> django admin显示字段中文
editable          -> django admin是否可以被编辑
error_messages    -> 错误信息欠
help_text         -> django admin提示
validators    -> django form ,自定义错误信息(欠)
 
test = models.EmailField(max_length=19,null=True,error_messages={'invalid': '请输入密码'})
#当用户什么都没有填的时候提示:请输入密码

插入语句小例子,自动创建时间戳:

models.py:

class UserGroup(models.Model):
     uid = models.AutoField(primary_key=True)
     caption = models.CharField(max_length=32,unique=True)
     ctime = models.DateTimeField(auto_now=True,null=True)
     uptime = models.DateTimeField(auto_now=True,null=True)

views.py:

models.UserGroup.objects.create(caption='xiaohuo')

image.png

注意:

obj = UserGroup.objects.filter(id=1).update(caption='CEO') #这种更新uptime的更新是不生效的,jdango不支持,支持下面的形式
obj = UserGroup.objects.filter(id=1).first() #这种uptime时间才会发生变化,如果有多个值就取第一个,那么obj就不是一个列表而是一个对象了。
obj= "CEO"
obj.save()

用户的下拉框例子:

models.py:

user_type_choices = (#这几个选项会放到内存里面,而在数据库里面生成的时候只是数字
   (1, '超级用户'),
   (2, '普通用户'),
   (3, '普普通用户'),
)
user_type_id = models.IntegerField(choices=user_type_choices,default=1)

image.png

#jdangoadmin里面会显示选择用户的下拉框,数字存数据库中,列表放内存中

根据类对数据库表中的数据进行各种操作:

user_group = models.ForeignKey("UserGroup",to_field='uid',default=1)

#ForeignKey外键关联  "UserGroup"将这个表关联过来   to_field='uid' #与uid字段相关联 ,default=1 #数字也就是uid号

image.png

ForeignKey封装了一个对象,想取值就用.去取值:

# user_list = Userinfo.objects.all()  #user_list.id什么的是取本类的相关值
# for row in user_list:
#     print(row.user_group_id)
#     print(row.user_group.uid)
#     print(row.user_group.caption)

创建数据一对多的创建:

models.UserInfo.objects.create(
   username='root1',
   password='123',
   email="dadsad",
   test="dadsa",
   user_group= models.UserGroup.objects.filter(id=1).filter() #将查询外键做成一个对象添加
)
models.UserInfo.objects.create(
   username='root1',
   password='123',
   email="dadsad",
   test="dadsa",
   user_group_id = 1 #表属性如果已经设置了外键了,就不用上面的方式,直接输入外键的值创建字段
)
作者:chaishaopeng 分类:Django学习 浏览:1658 评论:0
留言列表
发表评论
来宾的头像