benadida / helios-server

Helios server
http://heliosvoting.org
Apache License 2.0
725 stars 344 forks source link

helios.models.MultipleObjectsReturned: get() returned more than one CastVote -- it returned 2! #285

Open ostasevych opened 3 years ago

ostasevych commented 3 years ago

I have caught the error when trying to click the link next 50 in the list of voters in the Ballot Tracking Centre: helios.models.MultipleObjectsReturned: get() returned more than one CastVote -- it returned 2!

Trying to investigate it I found that this is caused by ambiguity of the uniqueness of data, see more: https://stackoverflow.com/questions/22063748/django-get-returned-more-than-one-topic/66284066#66284066

I tried to follow the advise and replaced get() with filter() in models.py:

@property
  def vote_tinyhash(self):
    """
    get the tinyhash of the latest castvote
    """
    if not self.vote_hash:
      return None

    #OS: FIX ME, with vote_tinyhash getting error:
    # Internal Server Error: /helios/elections/*****/voters/list
    # MultipleObjectsReturned at /helios/elections/****/voters/list
    # get() returned more than one CastVote -- it returned 2!

#    return CastVote.objects.get(vote_hash = self.vote_hash).vote_tinyhash

    return CastVote.objects.all().filter(vote_hash = self.vote_hash)](url)

However, if I add the vote.tinyhash at the end I am getting error:

return CastVote.objects.all().filter(vote_hash = self.vote_hash).vote_tinyhash
2021-02-19T19:55:41.974511+00:00 app[web.1]: AttributeError: 'QuerySet' object has no attribute 'vote_tinyhash'](url)

If I am omitting it the url of the ballot appears to be broken, eg:

https://mydomain.tld/helios/v/%3CQuerySet%20%5B%3CCastVote:%20CastVote%20object%3E%5D%3E 

What and how it may be fixed?

ostasevych commented 3 years ago

Simple fix:

CastVotes = CastVote.objects.all().filter(vote_hash = self.vote_hash)
    for castvote in CastVotes:
      pass
    return CastVotes.last().vote_tinyhash

Probably last() should be used, as we are going to take the last vote()? Am I right?