标签: django-orm

使用 Django ORM (CROSS JOIN) 计算组合

我有三个相关的模型:Process,FactorLevel. AProcessFactors 存在多对多关系,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') 组成。计算 …

django django-orm django-queryset

5
推荐指数
1
解决办法
1596
查看次数

Django 覆盖查询中双下划线关系查找的行为

我的主要问题是:有没有办法改变相关查找的行为,例如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)

python sql django django-models django-orm

5
推荐指数
1
解决办法
955
查看次数

如何在django模型中选择相关的所以它不会产生很多子查询

我有很多模型以某种方式相互引用,例如:

港口指的是城市,而城市又指的是国家。然后在 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在这种情况下会以某种方式帮助我,但是如何在模型中正确使用它?

python sql django django-orm

5
推荐指数
1
解决办法
1109
查看次数

Django:更新多个对象属性

有没有更有效的方法可以用 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)

编辑移动变量一致。

python django django-orm

5
推荐指数
1
解决办法
1997
查看次数

Django .only() 导致最大递归深度超出错误?

我使用 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什么?

python django recursion django-models django-orm

5
推荐指数
1
解决办法
1129
查看次数

Use django ORM with multiprocessing?

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 …

python django django-orm python-multiprocessing

5
推荐指数
1
解决办法
794
查看次数

使用 Django ORM 预取间接相关的项目

我正在尝试优化我的审核系统的查询,使用 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)

django query-optimization django-orm

5
推荐指数
0
解决办法
133
查看次数

在不使用原始数据的情况下聚合联合查询的结果

我有一张看起来像这样的桌子

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)

django django-orm

5
推荐指数
0
解决办法
241
查看次数

在 Django 中使用“_id”

当我们将 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)

这是为什么?这里有什么我不明白的规则吗?

python django django-orm

5
推荐指数
1
解决办法
1523
查看次数

Django CheckConstraint:反向外键查找的元素不能为空

我有这些模型:

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为空?)

django django-models check-constraints django-orm django-q

5
推荐指数
1
解决办法
989
查看次数