SCo*_*vin 16 python django postgresql django-orm django-1.8
Django 1.8 将带有新的高级字段类型,包括依赖于PostgreSQL的ArrayField,并在数据库级别实现.
PostgreSQL的数组字段实现了一个append方法.
但是,我找不到任何关于附加项目的文档ArrayField.这显然非常有用,因为它允许更新字段而不将其全部内容从数据库转移回数据库.
这可能吗?如果不是将来可能的话?任何指向我错过的文档的指针都将非常感激.
为了澄清我的要求,这将是伟大的:
注意:这是幻想代码,我认为不会工作(我没试过)
# on model:
class Post(models.Model):
tags = ArrayField(models.CharField(max_length=200))
# somewhere else:
p = Post.objects.create(tags=[str(i) for i in range(10000)])
p.tags.append('hello')
Run Code Online (Sandbox Code Playgroud)
目前有没有办法做到这一点,而不诉诸原始的SQL?
Dan*_*kov 20
注意:OP代码绝对有效.我们只需要保存模型(因为这些只是模型字段,而不是关系).让我们来看看:
>>> p = Post.objects.create(tags=[str(i) for i in range(10000)])
>>> p.tags.append("working!")
>>> p.save()
>>> working_post = Post.objects.get(tags__contains=["working!"])
<Post: Post object>
>>> working_post.tags[-2:]
[u'9999', u'working!']
Run Code Online (Sandbox Code Playgroud)
ArrayFieldpython列表您可以使用 list 执行的所有操作,您可以使用ArrayField.甚至排序
ArrayField为python列表这意味着它保存了python列表的结构和元素.
小智 10
我认为您正在寻找的功能目前尚未实施(可能没有计划).许多Postgres contrib功能都源于这个kickstarter项目.
我发现新功能最有用的文档来自源代码本身.其中包含许多这些功能的原始拉取请求的链接.
关于所提到的数组函数的一个重要注意事项,它们是函数,可以说是在典型ORM的范围之外.
我希望这些信息很有用,你找到了解决这个问题的好方法.
这有效:
from django.db.models import F
from django.db.models.expressions import CombinedExpression, Value
post = Post.objects.get(id=1000)
post.tags = CombinedExpression(F('tags'), '||', Value(['hello']))
post.save()
Run Code Online (Sandbox Code Playgroud)
或者在更新条款中:
Post.objects.filter(created_on__lt=now() - timespan(days=30))\
.update(tags=CombinedExpression(F('tags'), '||', Value(['old'])))
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是使用自定义表达式。我使用 Django 1.11 和 Python 3.6(f 字符串)测试了以下代码。
from django.db.models.expressions import Func
class ArrayAppend(Func):
function = 'array_append'
template = "%(function)s(%(expressions)s, %(element)s)"
arity = 1
def __init__(self, expression: str, element, **extra):
if not isinstance(element, (str, int)):
raise TypeError(
f'Type of "{element}" must be int or str, '
f'not "{type(element).__name__}".'
)
super().__init__(
expression,
element=isinstance(element, int) and element or f"'{element}'",
**extra,
)
Run Code Online (Sandbox Code Playgroud)
该表达式可用于update():
Post.objects \
.filter(pk=1) \
.update(tags=ArrayAppend('tags', 'new tag'))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9950 次 |
| 最近记录: |