Django에서 4 개의 정수의 가능한 모든 조합을 선택하는 쿼리를 작성하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1631333

  •  06-07-2019
  •  | 
  •  

문제

나는 게임 웹 사이트를 작성하고 있습니다. 여기서 드로우는 일련의 4 자리입니다. 예 : 1234

나는 "4 자리 숫자를 기준으로 모든 승자를 선택할 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.
도움이 되었습니까?

해결책

숫자가 정렬 된 순서로 저장되도록 숫자를 저장하도록 코드를 조정하는 것이 좋습니다. 예 : 사용자가 "5262"에 넣으면 "2256"으로 저장해야합니다. 그런 다음 승리 한 자릿수 세트를 선택하면이를 분류하고 간단한 평등으로 필터링 할 수 있습니다. 이것은 가능한 모든 조합을 확인하는 것보다 훨씬 더 잘 수행됩니다.

다른 목적으로 분류되지 않은 선택이 필요한 경우 모델에 새로운 필드를 추가하십시오. sortedDigits 또는 비교할 수있는 것.

다른 팁

암호:

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가 모든 게임의 모델 객체라고 가정하고, 형식의 4 개의 선택한 숫자를 포함하는 텍스트 필드 번호가 있습니다. NNNN.

Python 2.5에 있다면 itertools 이 없습니다 permutations. 문서에는 사용할 수있는 구현이 있습니다. http://docs.python.org/library/itertools.html#itertools.permutations

숫자의 순서가 중요합니까?

그렇지 않은 경우 티켓의 자릿수를 정렬하고 오름차순 순서로 그리울 수 있습니다. 그런 다음 코드를 사용하십시오.

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

제쳐두고, 당신의 시도는 ... 블록을 제외하고는 승자가 없을 때 상황을 포착하지 못합니다. 그만큼 DoesNotExist 예외는 get 방법 (문서를 참조하십시오).

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

if winners
    # there are winners
    self.winner = True
else:
    # there are not winners
    self.winner = False
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top