我有三个相关的模型:Process,Factor和Level. AProcess与Factors 存在多对多关系,aFactor将拥有一个或多个Levels。我正在尝试计算Level与 a 相关的s 的所有组合Process。这很容易用 Pythonitertools作为模型方法来实现,但执行速度有点慢,所以我试图弄清楚如何使用 Django ORM 在 SQL 中执行这个计算。
楷模:
class Process(models.Model):
factors = models.ManyToManyField(Factor, blank = True)
class Factor(models.Model):
...
class Level(models.Model):
factor = models.ForeignKey(Factor, on_delete=models.CASCADE)
Run Code Online (Sandbox Code Playgroud)
示例:一个过程'Running'涉及三个Factors ( 'Distance', 'Climb', 'Surface'),每个s由多个Levels ( 'Long'/ 'Short', 'Flat'/ 'Hilly', 'Road'/ 'Mixed'/ 'Trail') 组成。计算 …
我的主要问题是:有没有办法改变相关查找的行为,例如MyModel.objects.filter(relationship__field="value")?
考虑这个设置。我与自定义管理器建立了一对多关系,该管理器过滤掉书籍active=False
from django.db import models
class ActiveOnly(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return super(ActiveOnly, self).get_queryset().filter(active=True)
class Author(models.Model):
name = models.TextField()
class Book(models.Model):
active = models.BooleanField()
author = models.ForeignKey(Author, related_name="books")
title = models.TextField()
objects = ActiveOnly()
Run Code Online (Sandbox Code Playgroud)
让我们创建一些数据:
jim = Author.objects.create(name="Jim")
ulysses = Book.objects.create(title="Ulysses", author=jim, active=True)
finnegans = Book.objects.create(title="Finnegan's Wake", author=jim, active=False)
bill = Author.objects.create(name="Bill")
hamlet = Book.objects.create(title="Hamlet", author=bill, active=False)
Run Code Online (Sandbox Code Playgroud)
从本质上讲,我永远不想处理不活跃的书籍。以下是一些用于测试各种场景的查询。
>>> Book.objects.all().count() # expecting the 1 active book: good
1
>>> jim.books.all() # also expecting only 1: …Run Code Online (Sandbox Code Playgroud) 我有很多模型以某种方式相互引用,例如:
港口指的是城市,而城市又指的是国家。然后在 django admin 我想在 list_display Ports 国家显示:
class Country(models.Model):
title = models.CharField()
class City(models.Model):
title = models.CharField()
country = models.ForeignKey(Country)
class Port(models.Model):
city = models.ForeignKey(City)
def __str__(self):
return self.city.county.title
Run Code Online (Sandbox Code Playgroud)
所以基本上每个端口 django 都会生成更多的查询。我认为select_related在这种情况下会以某种方式帮助我,但是如何在模型中正确使用它?
有没有更有效的方法可以用 F 表达式来做到这一点?一些如何减少命中数据库?
# 1st way hits DB twice per object
def something():
pks = [4, 2, 1, 3, 0]
for i in range(len(pks)):
mymodel.objects.get(pk=pks[i]).update(attr=i)
# 2nd way hits DB once per obj and once for the queryset
def something():
pks = [4, 2, 1, 3, 0]
order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pks)])
query = mymodel.objects.filter(pk__in=pks).order_by(order)
for i in range(len(query)):
query[i].attr = i
query[i].save()
Run Code Online (Sandbox Code Playgroud)
编辑移动变量一致。
我使用 Django 的.only()构造来仅查询我需要的列。
前任。
Trainer.objects.filter(id__in=ids).only('id', 'lives')
这是我写的一个简单的例子来重现这个:
class BaseTrainer(models.Model):
mode = models.IntegerField(help_text="An integer")
def __init__(self, *args, **kwargs):
super(BaseTrainer, self).__init__(*args, **kwargs)
self._prev_mode = self.mode
class Trainer(BaseTrainer):
name = models.CharField(max_length=100, help_text="Name of the pokemon")
trainer_id = models.CharField(max_length=10, help_text="trainer id")
badges = models.IntegerField(help_text="Power of the pokemon (HP)")
lives = models.PositiveIntegerField(default=sys.maxsize)
unique_together = ("name", "trainer_id")
def __init__(self, *args, **kwargs):
super(Trainer, self).__init__(*args, **kwargs)
self._temp = self.lives
@classmethod
def test(cls):
t = Trainer.objects.only('trainer_id').all()
print(t)
Run Code Online (Sandbox Code Playgroud)
我只需要 id 和 name 字段,这是肯定的。原因是maximum recursion depth exceeded什么?
I have a Django ORM database (mysql or sqlite), and would like to process each row with a fairly computationally intensive operation. What I have right now is something like:
entries = Entry.objects.filter(language='')
for e in entry:
e.language = detect_language(e.text)
e.save()
Run Code Online (Sandbox Code Playgroud)
If the database was the bottleneck, I would use a transaction to speed it up. However, the detect_language function is what takes the most time. I could try to run the script multiple times in parallel, but that would …
我正在尝试优化我的审核系统的查询,使用 Django 和 DRF 构建。我目前坚持重复检索:目前,我有类似的东西
class AdminSerializer(ModelSerializer):
duplicates = SerializerMethodField()
def get_duplicates(self, item):
if item.allowed:
qs = []
else:
qs = Item.objects.filter(
allowed=True,
related_stuff__language=item.related_stuff.language
).annotate(
similarity=TrigramSimilarity('name', item.name)
).filter(similarity__gt=0.2).order_by('-similarity')[:10]
return AdminMinimalSerializer(qs, many=True).data
Run Code Online (Sandbox Code Playgroud)
这工作正常,但至少为每个要显示的项目执行一个额外的查询。另外,如果有重复项,我会做额外的查询来填充AdminMinimalSerializer,其中包含重复项的字段和相关对象。我可能可以通过使用prefetch_related内部序列化程序来减少开销,但这并不能阻止我对每个项目进行多次查询(假设我只有一个相关项目要预取AdminMinimalSerializer,我仍然有 ~2N + 1 个查询:1项,N 为重复项,N 为重复项的相关项)。
我已经看过了Subquery,但是我无法检索一个对象,只能检索一个 id,这在我的情况下还不够。我尝试在Prefetch对象和.annotate.
我也尝试过类似的东西Item.filter(allowed=False).prefetch(Prefetch("related_stuff__language__related_stuff_set__items", queryset=Items.filter..., to_attr="duplicates")),但该duplicates属性被添加到“related_stuff__language__related_stuff_set”,所以我不能真正使用它......
我欢迎任何想法;)
编辑:真正的代码在这里。下面的玩具示例:
# models.py
from django.db.models import Model, CharField, ForeignKey, CASCADE, BooleanField
class Book(Model):
title = CharField(max_length=250)
serie …Run Code Online (Sandbox Code Playgroud) 我有一张看起来像这样的桌子
date car_crashes city
01.01 1 Washington
01.02 4 Washington
01.03 0 Washington
01.04 2 Washington
01.05 0 Washington
01.06 3 Washington
01.07 4 Washington
01.08 1 Washington
01.01 0 Detroit
01.02 2 Detroit
01.03 4 Detroit
01.04 2 Detroit
01.05 0 Detroit
01.06 3 Detroit
01.07 1 Detroit
Run Code Online (Sandbox Code Playgroud)
我想知道全国每天发生多少次车祸,我可以用这个来做:
Model.values("date") \
.annotate(car_crashes=Sum('car_crashes')) \
.values("date", "car_crashes")
Run Code Online (Sandbox Code Playgroud)
现在,让我们假设我有一个这样的数组:
weights = [
{
"city": "Washington",
"weight": 1,
},
{
"city": "Detroit",
"weight": 2,
}
]
Run Code Online (Sandbox Code Playgroud)
这意味着底特律的车祸应乘以 2,然后再与华盛顿的相加。
可以这样做:
from django.db.models import IntegerField …Run Code Online (Sandbox Code Playgroud) 当我们将 ORM 与某些使用外键的模型一起使用时,我对 Django 如何处理 '_id' 属性感到有些困惑。例如:
class CartItem(models.Model):
user = models.ForeignKey('accounts.CustomUser', related_name='carts', on_delete=models.CASCADE, verbose_name='User')
product = models.ForeignKey('pizza.Product', related_name='carts', on_delete=models.CASCADE, verbose_name=_('Product'))
quantity = models.SmallIntegerField(verbose_name=_('Quantity'))
Run Code Online (Sandbox Code Playgroud)
当我将 ORM 与“过滤器”一起使用时,我可以轻松使用以下内容:
CartItem.objects.filter(user=1, product=1, quantity=1)
Run Code Online (Sandbox Code Playgroud)
Django 有点“看到”,我指的是“id”,但是当我使用完全相同的代码行,但使用“创建”而不是“过滤器”时:
CartItem.objects.create(user=1, product=1, quantity=1)
Run Code Online (Sandbox Code Playgroud)
然后它抛出一个错误说:
无法分配“1”:“CartItem.user”必须是“CustomUser”实例。
要创建它,我需要使用:
CartItem.objects.create(user_id=1, product_id=1, quantity=1)
Run Code Online (Sandbox Code Playgroud)
这是为什么?这里有什么我不明白的规则吗?
我有这些模型:
class Container(models.Model):
...
class Meta:
constraints = [
models.CheckConstraint(
check=~Q(elements=None),
name='container_must_have_elements'
),
]
class Element(models.Model):
container = models.ForeignKey(Container),
related_name='elements',
on_delete=models.CASCADE
)
Run Code Online (Sandbox Code Playgroud)
我想强制每个Container对象必须至少有一个Element通过外键关系引用它的约束。
如您所见,我已经添加了一个检查约束。但是,对象~上的否定运算符Q似乎是被禁止的。django.db.utils.NotSupportedError: cannot use subquery in check constraint当我尝试应用生成的迁移时,我得到了。
如果没有否定运算符,约束似乎是有效的(它只会由于数据完整性错误而失败)。
有没有另一种方法可以表达这个约束,以便它支持CheckConstraint?(例如,有没有办法检查集合是否elements为空?)