我正在写一个游戏网站,其中抽奖是一系列四位数字。例如1234
我试图在django中写一个查询,根据输入的四位数选择所有获胜者。获胜者是相同数字或相同组合的任意组合,1 2 3 4,2 3 1 4,4 1 3 2都是赢家。
如何最有效地编写此查询。
---------------------编辑,抱歉没有提供模型样本,如下所示:-----------
class Draw(models.Model):
digit1 = models.PositiveSmallIntegerField(null=True,blank=True)
digit2 = models.PositiveSmallIntegerField(null=True,blank=True)
digit3 = models.PositiveSmallIntegerField(null=True,blank=True)
digit4 = models.PositiveSmallIntegerField(null=True,blank=True)
draw_date = models.DateTimeField()
closed = models.BooleanField()
winner = models.BooleanField()
def __unicode__(self):
return "Draw For Week Ending %s" %(self.draw_date)
def get_absolute_url(self):
return "/draw/%s/" % (self.draw_date)
def save(self, force_insert=False, force_update=False):
if self.digit1 and self.digit2 and self.digit3 and self.digit4:
#check if there are winners
try:
winners = Ticket.objects.filter(draw=self.id,digit1=self.digit1,digit2=self.digit2,digit3=self.digit3,digit4=self.digit4)
self.winner = True
except Ticket.DoesNotExist:
self.winner = False
#close & save draw/winners
self.closed = True
# Add new Draw for following week.
new_date = self.draw_date + datetime.timedelta(hours=168)
new_draw= Draw(draw_date=new_date)
new_draw.save()
super(Draw, self).save(force_insert, force_update) # Call the "real" save() method.
class Serial(models.Model):
serial = models.CharField(max_length=4)
closed = models.BooleanField(unique=False)
def __unicode__(self):
return "%s" %(self.serial)
def get_absolute_url(self):
return "/draw/serial/%s/" % (self.serial)
class Ticket(models.Model):
draw = models.ForeignKey(Draw)
digit1 = models.PositiveSmallIntegerField()
digit2 = models.PositiveSmallIntegerField()
digit3 = models.PositiveSmallIntegerField()
digit4 = models.PositiveSmallIntegerField()
date = models.DateField(auto_now_add=True,editable=False)
active = models.BooleanField(default=True)
serial_used = models.ForeignKey(Serial,related_name="ticket_serial_used")
def __unicode__(self):
return "#: %s - %s" %(self.id,self.draw)
def get_absolute_url(self):
return "/ticket/%s/" % (self.id)
def save(self, force_insert=False, force_update=False):
if self.serial_used:
serial = Serial.objects.get(pk=self.serial_used.id)
serial.closed = True
serial.save()
super(Ticket, self).save(force_insert, force_update) # Call the "real" save() method.
答案 0 :(得分:5)
我建议调整代码以保存数字,以便按排序顺序保存。例如。如果用户输入“5262”,则应将其存储为“2256”。然后,当您选择一组获胜数字时,您可以对这些数字进行排序,并通过简单的相等进行过滤。这比尝试检查所有可能的组合要好得多。
如果您需要将未排序的选项用于其他目的,请将新字段添加到模型sortedDigits
或其他内容,以便进行比较。
答案 1 :(得分:0)
代码:
from itertools import permutations
winning_numbers = "1234"
winning_combinations = map(lambda v: "".join(v), list(permutations(winning_numbers, 4)))
winners = GamesPlayed.objects.filter(numbers__in=winning_combinations)
假设GamesPlayed是所有游戏的模型对象,文本字段编号包含NNNN
格式的四个选定数字。
如果您使用的是Python 2.5,itertools
没有permutations
。文档有一个可以使用的实现:http://docs.python.org/library/itertools.html#itertools.permutations
答案 2 :(得分:0)
数字的顺序是否重要?
如果没有,您可以对故障单的数字进行排序并按升序绘制,然后使用您的代码
winners = Ticket.objects.filter(draw=self.id,digit1=self.digit1,digit2=self.digit2,digit3=self.digit3,digit4=self.digit4)
顺便说一下,当没有获胜者时,你的尝试...除了阻止将无法捕捉到这种情况。 DoesNotExist
方法(see docs)抛出了get
异常。
如果没有中奖彩票,filter
方法将返回空的查询集,但不会引发错误。然后,您可以使用if语句检查是否有获胜者。
if winners
# there are winners
self.winner = True
else:
# there are not winners
self.winner = False