varad
varad

Reputation: 8029

python django continous checking for validation of user and date

I have models :

class Participant(models.Model):
    user = models.CharField(max_length=20)
    date = models.DateTimeField()

    def __unicode__(self):
        return self.user

class Winner(models.Model):
    phone_no = models.CharField(max_length=20)
    win_date = models.DateTimeField()

    def __unicode__(self):
        return self.user

Here what I want is go generate a winner randomly from my Participant model.

I want to check if the randomly generated winner has won the game in past then I want to check if the won date difference between last time and now is greater then 4 month. If it is greater then user can win the game else again generate random user.

For this I have done:

player_list = Participant.objects.all()
winner = random.choice(player_list)
next_check = Winner.objects.filter(user=winner) 
if next_check:
    if (date.today() - timedelta(days= 4*365/12)) > next_check.win_date.date():
    #what if the user has won 5 times in past
        final_winner = winner
    else:
        # Again generate winner randomy and again check for the date is greater than 4 month

I have gone with this :

final_winner = None
while not final_winner:
    winner = random.choice(player_list)
    next_check = Winner.objects.filter(user=winner)
    if next_check:
    #wht if the user has won previously and what if the user has won many times previously
        if (date.today() - timedelta(days= 4*365/12)) > next_check.win_date.date():
            final_winner = winner

Can anyone guide me through this .

Thank you

Upvotes: 0

Views: 88

Answers (1)

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52203

First of all, your model hierarchy is not well-designed. Both Participant and Winner models serve to similar purposes and have the same fields.

Moreover, it looks like Participant is the superset of Winner since everyone will be defined as participant at first than one of them will win the game and become a winner. So, I would recommend you to create Winner by subclassing from Participant and define same fields in the super class like below:

class Participant(models.Model):
    user = models.ForeignKey('auth.User')
    creation_date = models.DateTimeField()
    phone_no = models.CharField(max_length=20)

    def __unicode__(self):
        return self.user.email

class Winner(Participant):
    win_date = models.DateTimeField()

One beautiful thing about this approach is that Django will create an implicit OneToOneField field from winner to participant so you'll be directly connected to participant details of a winner automatically.


As for your actual question, about checking if a user has won any game in the last 4 months, you can do the following:

from datetime import timedelta
from django.utils.timezone import now

def has_won_any_game_since(user, period):
    return Winner.objects.filter(user=user, win_date__gt=now() - period).exists()

def get_random_winner():
    player_list = list(Participant.objects.all())
    four_months = timedelta(days=120) # ~4 months

    while len(player_list) > 0:
        player = random.choice(player_list)
        if not has_won_any_game_since(player.user, four_months):
            return player
        else:
            player_list.remove(player)
    else:
        return None

>>> winner = get_random_winner()
<Winner: [email protected], win_date='07/23/2014 07:23:86'> # win_date is supposed to be less than 120 days.  

Hope this helps.

Upvotes: 1

Related Questions