0

这是一个奇怪的问题,所以提前抱歉。我在 Django Rest 中有一个如下所示的模型:

class BaseModel(models.Model):
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)

   class Meta:
        abstract = True

class Foo(BaseModel):
    barId = models.ForeignKey(Bar, unique=False)
    fizzId = models.ForeignKey(Fizz, unique=False)
    buzzId = models.IntegerField(unique=False)
    value = models.TextField()

而且我有一个 ViewSet 需要返回具有给定 {request_barId、request_buzzId、lastUpdateDate} 的所有 Foo 的列表。这很简单,

foobar = Foo.objects.filter(
buzzId=request_buzzId,
modified_date__gt=request_lastUpdateDate,
barId=request_barId)

这就是问题所在。BuzzId 有一个默认值,即指定的 BuzzId 需要覆盖的基本列表,替换基本列表上的实例那是我有点迷路的地方。我有一个解决方案,但我觉得它不是特别优雅,并且有一种方法可以做到这一点。这是我做覆盖的代码:

base_foobar = Foo.objects.filter(
buzzId=base_buzzId,
modified_date__gt=request_lastUpdateDate,
barId=request_barId).exclude(
        fizzId__in=[o.fizzId for o in foobar])
result = foobar | base_foobar

这看起来真的很笨拙。有没有办法清理这个?

编辑:为了澄清,假设元组 { 1, 0, '01-01-1970' } 的列表表示基本集 (buzzId: 0),并返回包含 fizzIds { 1, 2, 3 的对象列表, 10}。假设元组 { 1, 1, '01-01-1970' } 表示某个buzzId 对完整字符串集的请求。如果我们说我们的 BuzzId 为 1(称为增强)匹配 Foos 和 fizzIds { 2, 10, 15, 20 },那么我们的结果集应该看起来像

{ (base) 1, (augment) 2, (base) 3, (augment) 10, (augment) 15, (augment) 20 }

这清楚了吗?

4

1 回答 1

0

您可以使用Q组合成一个语句:

result = (Foo.objects
    .filter(
        Q(
            modified_date__gt=request_lastUpdateDate,
            barId=request_barId
        ) 
        &
        (
            Q(buzzId=request_buzzId) 
            |
            (
                Q(buzzId=base_buzzId)
                & 
                ~Q(fizzId__in=[o.fizzId for o in foobar])
            )
        )
    )
    .order_by( '-buzzId' if request_buzzId < base_buzzId else 'buzzId')
    )[0] # fetch first result only

另外,请在将来格式化所有代码。它不必像我一样,但它肯定有助于阅读你的问题。

于 2017-03-03T16:03:17.023 回答