2016-07-25 7 views
0

Django (1.9.6)를 처음 사용하고 Foreign (외국)에 포함 된 정보를 참조해야하는 ModelForm에서 필드의 유효성을 검사 할 수 있는지 이해하려고합니다. 참조 된 모델의 키.Django ModelForm 비 형식 데이터를 사용하여 유효성 검사

은 어떻게 OrderForm에 "num_tickets"에 대한 사용자 입력 값이 외국를 통해 연결되어있는 이벤트 클래스 필드 "을 tickets_remaining "보다 작거나 같은 것을 확인할 수 있습니다 중요한 관계?

나는 사용자가 이미 특정 이벤트 페이지에 액세스하고 있으며, 이미 티켓을 구입하기 위해 선택한으로 OrderForm주문 클래스에서 이벤트 필드을 노출하고 싶지 않아요.

Models.py

class Order(models.Model): 

    first_name = models.CharField('First Name', max_length=120,null=False, blank=False) 
    last_name = models.CharField('Last Name', max_length=120, null=False, blank=False) 
    email = models.EmailField('Email', null=False, blank=False) 
    event = models.ForeignKey(Event) 
    num_tickets = models.PositiveIntegerField('Tickets', null=False, blank=False, validators=[MinValueValidator(0)]) 
    total_price = models.DecimalField('Total', max_digits=8, decimal_places=2, default=0.0) 
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) 

class Event(models.Model): 

    event_name = models.CharField(max_length=200) 
    price = models.DecimalField(max_digits=8, decimal_places=2, default=00.00, validators=[MinValueValidator(0)]) 
    tickets_remaining = models.PositiveIntegerField(default=300) 

Forms.py

class OrderForm(forms.ModelForm): 

class Meta: 
    model = Order 
    fields = ['first_name', 'last_name', 'email', 'num_tickets'] 

def clean_num_tickets(self): 
    tickets = self.cleaned_data["num_tickets"] 

    # validation Logic. Want to ensure a user cannot purchase more 
    # tickets than what an event has for "tickets_remaining" 

    return tickets 

답변

1

첫 번째 장소에서 이벤트와 순서를 연결하는 방법 당신은 표시되지 않습니다. 그렇게하지 않았다면 사용 가능한 티켓을 확인하는 것보다 문제가 더 많습니다.

보기에서 해당 이벤트를 양식 인스턴스화로 전달하는 것이 좋습니다. 그런 다음 둘 모두를 사용하여 주문을 해당 이벤트와 연관시키고 티켓을 검증 할 수 있습니다. 를 인스턴스화 할 때

class OrderForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     self.event = kwargs.pop('event', None) 
     super(OrderForm, self).__init__(*args, **kwargs) 

    def clean_num_tickets(self): 
     tickets = self.cleaned_data["num_tickets"] 
     if tickets > self.event.tickets_remaining: 
      raise ValidationError('Too many tickets') 
     return tickets 

    def save(self, commit=False): 
     order = super(OrderForm, self).save(commit=False) 
     order.event = self.event 
     if commit: 
      order.save() 
     return commit 

지금 형태로 이벤트를 전달합니다

form = OrderForm(request.POST, event=event) 
+0

내가 크게 도움을 주셔서 감사합니다. 장고 튜토리얼을 살펴 보았지만, ModelForm의 생성자에 과부하가 걸리지 않았다. 이것은 틀을 더 잘 이해하는데 도움이 될 것입니다. – JR90