2009-10-27 5 views
1

저는 게임 웹 사이트를 작성하고 있습니다. 여기에서 추첨은 4 자리 숫자로 이루어집니다. 예를 들어 1234django에서 가능한 모든 4 개의 정수 조합을 선택하는 쿼리를 작성하는 방법은 무엇입니까?

내가 입력 한 4 자리 숫자를 기준으로 모든 승자를 선택하는 쿼리를 작성하려고합니다. 승자는 같은 숫자 또는 동일한 조합의 조합입니다 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

어떻게 번호를 선택한 플레이어를 저장 측면에서 귀하의 모델 설정은? – lemonad

+0

모델을 보지 않고도 대답 할 수 없습니다. –

+0

위의 모델 선언을 참조하십시오. Save 메서드가 Draw 모델에서 재정의되었을 때 승자인지 확인하려고합니다. – Rasiel

답변

5

숫자를 저장하여 정렬 된 순서로 저장되도록 코드를 조정하는 것이 좋습니다. 예 : 사용자가 "5262"를 입력하면 "2256"으로 저장해야합니다. 그런 다음 수상한 조합을 선택하면이를 정렬하고 간단한 동등성으로 필터링 할 수 있습니다. 가능한 모든 조합을 확인하는 것보다 훨씬 효과적입니다.

다른 용도로 정렬되지 않은 선택이 필요한 경우 비교할 수 있도록 모델 sortedDigits 또는 무언가에 새 필드를 추가하십시오.

+0

이것은 내 모델을 변경한다는 의미입니다 4 자릿수에서 1 자릿수까지의 선언? – Rasiel

+0

나는 그것이 더 간단 할 것이라고 생각한다. 양자 택일로, 당신은 단지 숫자를 정렬하고 귀하의 필터가 승리 콤보에 대해, 네 자리에 하나씩 4 개의 동등한 검사를 할 수 있습니다. 어느 쪽이든 작동합니다. –

+0

이 작품 덕분에!, 난 그냥 네 자리와 각 숫자에 대한 평등 확인을 했어 – Rasiel

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입니다.

파이썬 2.5의 경우 itertools에는 permutations이 없습니다. 문서에는 다음과 같이 사용할 수있는 구현이 있습니다. http://docs.python.org/library/itertools.html#itertools.permutations

+0

작동하는 것처럼 들리지만 ... (위의 모델 선언을 기반으로합니까?) : winners = Ticket.objects.filter (digit1__in = winning_combinations, digit2__in = winning_combinations, digit3__in = winning_combinations, digit4__in = winning_combinations) – Rasiel

+0

위의 모델을 바탕으로 대답을 표시 할 수 있습니까? 기본적으로, 여기에서 일을하고 있지만 문자열을 사용할 때 텍스트 필드 번호에 대해 확신 할 수 없으며 4 개의 다른 정수를 사용하고 있습니다. – Rasiel

+0

나는 winning_numbers가 될 것이라고 가정합니다. winning_numbers = "% s % s % s % s"% (self.digit1, self.digit2, self.digit3, self.digit4) – Rasiel

0

숫자의 순서가 중요합니까? 당신이 티켓 숫자를 정렬 오름차순으로 그리는 수없는 경우

, 다음 때 상황을 잡을 것이다 블록을 제외하고 ..., 옆으로 다음으로 시도 코드

winners = Ticket.objects.filter(draw=self.id,digit1=self.digit1,digit2=self.digit2,digit3=self.digit3,digit4=self.digit4) 

을 사용하여이 승자가 아닙니다. DoesNotExist 예외는 get 메서드 (see docs)에 의해 발생합니다.

당첨 티켓이없는 경우 filter 메서드는 빈 쿼리 세트를 반환하지만 오류는 발생하지 않습니다. 그런 다음 if 문을 사용하여 승자가 있는지 확인할 수 있습니다.

if winners 
    # there are winners 
    self.winner = True 
else: 
    # there are not winners 
    self.winner = False 
+0

안녕하세요, 숫자의 순서는 중요하지 않습니다. 당첨 확률은 중요하지 않지만 티켓 번호를 정렬하는 방법과 성공한 숫자의 가능한 모든 조합을 선택하는 논리로 변환하는 방법을 잘 모르겠습니다. 제발 좀 명확히 해줄 수 있니? – Rasiel

+0

Try Except Block을 언급 해 주셔서 감사합니다. – Rasiel

+0

_numbers_ 대신 _digits_ 티켓을 정렬하는 것이 더 명확했을 수도 있습니다. 파이썬으로 목록을 정렬하는 것은 간단합니다. 모든 조합을 동일한 정렬 목록으로 줄일 수 있기 때문에 모든 조합을 계산할 필요가 없습니다. 희망은 그 말이 맞습니다. – Alasdair

관련 문제