按用户和对象过滤Django模型

时间:2018-10-06 19:45:22

标签: django django-models

我正在通过一个虚拟示例来学习Django,但是在理解如何理解授权用户正确过滤Django模型方面有困难。

在我看来,我想列出与用户投资组合相关的交易。下面的代码运行,但是尝试访问't'的结果时出现错误:

“ ValueError:用于精确查找的QuerySet值必须限制为使用切片的一个结果。”

非常感谢您的帮助。

if request.user.is_authenticated:
    # Get model data
    pf = Portfolio.objects.filter(user=request.user)
    t = Transaction.objects.filter(pf=pf)

我的模型如下:

from django.db import models
from django.contrib.auth.models import User


class Portfolio(models.Model):

    # Portfolio has one user associated with it
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    name = models.CharField(max_length=100, default='-')

    def __str__(self):
        return self.name


class Transaction(models.Model):
    # Transaction has one equity associated with it
    equity = models.ForeignKey('Equity', on_delete=models.CASCADE, null=True)

    # Transaction has one portfolio associated with it
    pf = models.ForeignKey('Portfolio', on_delete=models.CASCADE)

    BUY = 'BUY'
    SELL = 'SELL'
    BUY_OR_SELL = (
        (BUY, 'BUY'),
        (SELL, 'SELL'),
    )
    action = models.CharField(choices=BUY_OR_SELL, default=BUY, max_length=5)
    num = models.FloatField(default=1)
    price = models.FloatField(default=0)
    date = models.DateField('date')
    fee = models.FloatField(default=0)

    def __str__(self):
        return f'{self.equity}, {self.num}x{self.price}, {self.date:%d %b %Y}'


class Equity(models.Model):
    class Meta:
        verbose_name_plural = "Equities"

    CUR_EUR = 'EUR'
    CUR_GBP = 'GBP'
    CUR_USD = 'USD'
    CURRENCY_CHOICES = (
        (CUR_EUR, 'EUR'),
        (CUR_GBP, 'GBP'),
        (CUR_USD, 'USD'),
    )
    symbol = models.CharField(max_length=20, default='-')
    exchange = models.CharField(max_length=100, default='-')
    currency = models.CharField(max_length=15, choices=CURRENCY_CHOICES, default=CUR_USD)

    def __str__(self):
        return self.symbol

非常感谢!

1 个答案:

答案 0 :(得分:1)

pfPortfolio对象的集合,因此您可以使用__in lookup [Django-doc]进行查询:

Transaction.objects.filter(pf__in=pf)

或者,如果您对Porfolio对象本身不感兴趣,可以进行如下查询:

Transaction.objects.filter(pf__user=request.user)

以下查询将导致类似以下查询:

SELECT transaction.*
FROM transaction
JOIN portfolio ON transaction.pf_id = portfolio.id
WHERE porfolio.user_id = 123

(带有{{1}的123id