2016-07-25 3 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

私は大いに助けに感謝。私はDjangoチュートリアルを行ったが、ModelFormのコンストラクタのオーバーロードは明示的に触れられていなかった。これは間違いなくフレームワークの理解に役立ちます。 – JR90

関連する問題