DJango JsonField 和ListField实现
org-docs: https://django-mysql.readthedocs.io/en/latest/model_fields/json_field.html
Installation
Install it with pip:
$ python -m pip install django-mysql
Or add it to your project’s requirements.txt
.
Add 'django_mysql'
to your INSTALLED_APPS
setting:
INSTALLED_APPS = (
...
'django_mysql',
)
Django-MySQL comes with some extra checks to ensure your configuration for Django + MySQL is optimal. It’s best to run these now you’ve installed to see if there is anything to fix:
$ ./manage.py check
类JSONField
(** kwargs )
用于存储JSON的字段。Python的数据类型可以是str
, int
,float
,dict
,或list
-由支持基本上什么json.dumps
。这些类型之间没有限制-如果您期望它仅存储JSON对象,这可能会令人惊讶dict
。
因此,例如,以下所有工作:
mymodel.myfield = "a string"
mymodel.myfield = 1
mymodel.myfield = 0.3
mymodel.myfield = ["a", "list"]
mymodel.myfield = {"a": "dict"}
此字段需要Django 1.8+和MySQL 5.7+。这两个要求都由该字段检查,如果您不了解这两个要求,则在运行Django的检查时,您会为它们找到明智的错误。
警告
如果您给字段一个default
,请确保它是可调用的,例如一个函数,或dict
或list
类本身。错误地使用可变对象(例如default={}
)会创建在字段的所有实例之间共享的单个对象。如果将平原list
或dict
实例用于 default
,则有一个字段检查是否出错,因此对此有一定的保护措施。
提供丰富的默认值的正确方法是定义一个返回它的模块级函数,以便可以在迁移中序列化它。例如:{'foo': 'bar'}
def my_default():
return {'foo': 'bar'}
class MyModel(Model):
attrs = JSONField(default=my_default)
from django_mysql.models import JSONField, Model class ShopItem(Model): name = models.CharField(max_length=200) attrs = JSONField() def __str__(self): return self.name
Django ListField
两个字段的数据储存列表,Django的的成年版本 CommaSeparatedIntegerField
,表兄弟 django.contrib.postgres
的 ArrayField
。有两个版本: ListCharField
,基于CharField
和适用于存储最大大小较小的列表,以及ListTextField
,基于 TextField
和因此适用于(近)无限制大小的列表(基础LONGTEXT
MySQL数据类型的最大长度为2 32 -1个字节)。
- 类
ListCharField
(base_field,size = None,** kwargs ) -
用于存储所有符合的数据列表的字段
base_field
。base_field
-
列表中存储的数据的基本类型。当前,必须是
IntegerField
,CharField
或其任何子类-ListCharField
本身除外。
size
-
(可选)设置列表中的最大项目数。仅在表单验证时检查,而不在模型保存时检查!
作为
ListCharField
的子类CharField
,CharField
也可以设置任何选项。最重要的是,您需要设置max_length
以确定在数据库中保留多少个字符。示例实例:
from django.db.models import CharField, Model from django_mysql.models import ListCharField class Person(Model): name = CharField() post_nominals = ListCharField( base_field=CharField(max_length=10), size=6, max_length=(6 * 11) # 6 * 10 character nominals, plus commas )
在Python中,只需将字段的值设置为列表即可:
>>> p = Person.objects.create(name='Horatio', post_nominals=['PhD', 'Esq.']) >>> p.post_nominals ['PhD', 'Esq.'] >>> p.post_nominals.append('III') >>> p.post_nominals ['PhD', 'Esq.', 'III'] >>> p.save()
在save()上验证
对数据库执行从列表到字符串的转换时,请
ListCharField
进行一些验证,ValueError
如果有问题,则会进行提示,以避免保存错误的数据。以下是无效的:- 字符串表示形式中包含逗号的任何成员
- 任何字符串表示形式为空字符串的成员
默认表单字段为
SimpleListField
。
- 类
ListTextField
(base_field,size = None,** kwargs ) -
与相同
ListCharField
,但以a为后缀TextField
,因此长度的限制要少得多。没有max_length
争论。示例实例:
from django.db.models import IntegerField, Model from django_mysql.models import ListTextField class Widget(Model): widget_group_ids = ListTextField( base_field=IntegerField(), size=100, # Maximum of 100 ids in list )
JSON字段替换
classJSONReplace(expression, data) Given expression that resolves to some JSON data, replaces existing paths in it using the dictionary data of JSON paths to new values. If any JSON path within the data dictionary does not match, or if expression is NULL, it returns NULL. Paths that do not exist in the original data are ignored. Note that if expression is a string, it will refer to a field, whereas keys and values within the pairs dictionary will be wrapped with Value automatically and thus interpreted as the given string. If you want a key or value to refer to a field, use Django’s F() class. Docs: MySQL. >>> # Reset all items' monthly_sales to 0 directly in MySQL >>> ShopItem.objects.update( ... attrs=JSONReplace('attrs', {'$.monthly_sales': 0}) ... )