使用非表单数据的 Django ModelForm 验证
Django ModelForm Validation using non form data
我是 Django (1.9.6) 的新手,我想了解是否可以验证 ModelForm 上的字段,该字段需要引用引用模型的外键中包含的信息.
如何验证用户在 OrderForm 上为“num_tickets”输入的值是否小于或等于通过外键关系连接的Event class上的“tickets_remaining”字段?
我不想公开 上 Order class 的 Event 字段 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
您一开始就没有展示您是如何将订单与活动相关联的。如果您还没有这样做,那么您的问题不仅仅是验证可用的票证。
我建议将该事件从视图传递到表单实例化中。然后您可以使用它来将订单与该事件相关联,并验证门票。
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)
我是 Django (1.9.6) 的新手,我想了解是否可以验证 ModelForm 上的字段,该字段需要引用引用模型的外键中包含的信息.
如何验证用户在 OrderForm 上为“num_tickets”输入的值是否小于或等于通过外键关系连接的Event class上的“tickets_remaining”字段?
我不想公开 上 Order class 的 Event 字段 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
您一开始就没有展示您是如何将订单与活动相关联的。如果您还没有这样做,那么您的问题不仅仅是验证可用的票证。
我建议将该事件从视图传递到表单实例化中。然后您可以使用它来将订单与该事件相关联,并验证门票。
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)