pythondjangomany-to-manydjango-related-manager

Django error: The QuerySet value for an exact lookup must be limited to one result using slicing?


I have the following models schema:


class Site(models.Model):
    name = models.CharField(max_length=255)
    location = models.OneToOneField(GeoLocation, on_delete=models.PROTECT,
                                    related_name=RelatedNames.ADDRESS,
                                    blank=True, null=True)

    account = models.ForeignKey(Account, on_delete=models.PROTECT, related_name=RelatedNames.ACCOUNT_SITES)
    _type = models.IntegerField(choices=SiteTypeChoices.CHOICES)
    primary_email = models.EmailField(null=True, blank=True)

    objects = models.Manager()

    def __str__(self):
        return self.name

    def get_site_address(self):
        return str(self.location)


class SiteScore(models.Model):
    site = models.ForeignKey(Site, on_delete=models.CASCADE, related_name=RelatedNames.SITE_SCORES)
    date = models.DateTimeField(default=timezone.now)
    score = models.IntegerField(default=0)
    score_type = models.IntegerField(choices=SiteScoreChoices.CHOICES, null=True, blank=True)

class CustomUser(AbstractUser)
    username = None
    email = models.EmailField(_(Fields.EMAIL_ADDRESS), unique=True)

    accessed_sites = models.ManyToManyField(Site, related_name=RelatedNames.USERS)
    
    USERNAME_FIELD = Fields.EMAIL
    REQUIRED_FIELDS = []

I'm trying to filter out the site scores by date and by the user connected to the sites:

today = timezone.now().date()
worst_scores = SiteScore.objects.filter(date__date=today, site__users=self.request.user).order_by('-score')

But this raises this error:

The QuerySet value for an exact lookup must be limited to one result using slicing.

Also tried using:

        worst_scores = SiteScore.objects.filter(date__date=today, site__users__in=self.request.user)

But got error:

'CustomUser' object is not iterable

Solution

  • Few possible solutions

    The

    date__date=today
    

    is returning a result > 1 and as such it fails. Can you try and pass a more accurate today object (e.g.custom formed) and check if that works?

    What happens for this

    worst_scores = SiteScore.objects.filter(date__date=today, site__users=self.request.user).order_by('-score')[0] 
    

    Try using the .get() instead of filter() if you want to filter by just one particular item.

    For several, you can use the __in, e.g.

    products = Product.objects.filter(seller__in=account)

    so with the __in lookup [Django-doc].