我正在开展我的第一个django项目,这是一个体育博彩游戏。
以下是我的模特:
class Game(models.Model):
home_team = models.CharField(max_length=200)
away_team = models.CharField(max_length=200)
home_goals = models.IntegerField(default=None)
away_goals = models.IntegerField(default=None)
class Bet(models.Model):
gameid = models.ForeignKey(Game, on_delete=models.CASCADE)
userid = models.ForeignKey(User, on_delete=models.CASCADE)
home_goals = models.IntegerField()
away_goals = models.IntegerField()
score = models.IntegerField(default=None, null=True)
首先,我在目标字段中创建一个具有空值的游戏实例,然后用户下注。 游戏结束后,我会更新游戏目标字段。现在我需要像这样为每个用户分配点数:
WHEN bet.home_goals = game.home_goals AND bet.away_goals = game.away_goals THEN 2
WHEN game.home_goals > game.away_goals AND bet.home_goals > bet.away_goals THEN 1
WHEN game.home_goals < game.away_goals AND bet.home_goals < bet.away_goals THEN 1
WHEN bet.home_goals = bet.away_goals AND game.home_goals = game.away_goals THEN 1
ELSE 0
似乎我应该根据Game.home_goals和Game.away_goals的更新为每个用户创建一个POST_SAVE信号来更新Bet.score?但我不知道该怎么做
答案 0 :(得分:2)
我建议远离信号。一般来说,您应该在以下时间使用信号:
在您的情况下,只有Bet
模型对Game
保存/更改事件感兴趣。您可以直接访问Game
类。
我之所以这么说是因为信号往往会隐藏&#34;应用程序的代码/业务逻辑,使维护更加困难(因为它并不是很明显你有一些代码被执行)。
对我而言,它看起来像是一个常规视图的工作,你可以在其中添加游戏的分数和&#34;关闭&#34;它。可能需要一个额外字段(可以是BooleanField
或DateTimeField
)来表示Game
已结束。
请参阅以下示例:
<强> forms.py 强>
from .models import Game
from django import forms
from django.db import transaction
class GameForm(forms.ModelForm):
class Meta:
model = Game
fields = ('home_goals', 'away_goals')
# do everything inside the same database transaction to make sure the data is consistent
@transaction.atomic
def save(self):
game = super().save(commit=True)
for bet in game.bet_set.all():
if bet.home_goals == game.home_goals and bet.away_goals == game.away_goals:
bet.score = 2
elif <build_your_logic_here>:
bet.score = 1
else:
bet.score = 0
bet.save()
return game
<强> views.py 强>
from django.shortcuts import redirect
from .forms import GameForm
def end_game(request, game_id):
game = Game.objects.get(pk=game_id)
if request.method == 'POST':
form = GameForm(request.POST, instance=game)
if form.is_valid():
form.save()
return redirect('/gameboard/') # add here the relevant url where to send the user
else:
form = GameForm(instance=game)
return render(request, 'game_form.html', {'form': form})
如果出于某种原因,分数更改事件发生在多个点上(也就是说,模型已由应用程序的不同部分更新),在您的情况下,最佳选项将覆盖{ {1}}方法,如下所示:
<强> models.py 强>
save()
这将是一个类似于Signal的实现,但我会说更明确。正如我所提到的,我不认为这是您问题的最佳实现。这可能会降低您的应用程序速度,因为每次保存class Game(models.Model):
home_team = models.CharField(max_length=200)
away_team = models.CharField(max_length=200)
home_goals = models.IntegerField(default=None)
away_goals = models.IntegerField(default=None)
def save(self, *args, **kwargs):
# call the save method
super().save(*args, **kwargs)
# execute your extra logic
for bet in self.bet_set.all():
if bet.home_goals == self.home_goals and bet.away_goals == self.away_goals:
bet.score = 2
# rest of the if/else logic
bet.save()
实例时都会执行此for循环。
但是,如果您想了解有关信号的更多信息,我已写了一篇关于它的博文:How to Create Django Signals。