2014-09-01 45 views
0

我是Python和django的新手,并且无法实现模型表单验证。通过相关字段验证Django表格

我有一个表单,用户可以注册多个研讨会。我想验证表格,以便用户无法注册具有重叠时间段的研讨会。

我很难搞清楚如何访问我需要进行比较的时间数据。

问题:

  1. 我怎样才能从车间模型访问相关实时数据并将其过滤通过表单输入?
  2. 如何才能比较此数据将返回的多个项目?

当我运行下面的代码,我得到“太多的值解压缩”的错误。我明白为什么会发生这种情况,但不知道如何访问阵列中的信息来进行比较。

models.py

from django.db import models 
from django.contrib.auth.models import User 

class Workshop(models.Model): 
    title = models.CharField(max_length=100) 
    tuition = models.PositiveIntegerField() 
    start_time = models.DateTimeField() 
    end_time = models.DateTimeField(

class Registration(models.Model): 
    user = models.ForeignKey(User) 
    workshop = models.ManyToManyField(Workshop) 

forms.py

from django.db import models 
from django.forms import ModelForm 
from .models import Registration, Workshop 
from django.core.exceptions import ValidationError 


class RegistrationForm(ModelForm): 
    class Meta: 
     model = Registration 
     exclude = ['user'] 

    def clean(self): 
     workshop = self.cleaned_data.get('workshop') 
     startTime = Workshop.objects.get('workshop__start_time') 
     endTime = Workshop.objects.get('workshop__end_time') 
     if (startTime > endTime) or (startTime == startTime): 
      raise ValidationError("Workshop times overlap.") 
     return self.cleaned_data 

回答

0

如果你每次都检查是否出现重叠用户登记,这将是一个沉重的工作。相反,您可以做的是在研讨会插入时检查重叠。然后你可以有一个重叠的桌子,它可以存储重叠的工作间。这样,如果用户通过检查重叠表中的相同内容注册到两个重叠的研讨会,则可以警告用户。

0

您可以从django queryset中使用lt(小于)或gt(大于)methods。如果存在start_time > workshop.end_timestart_time = workshop.start_time提出错误的作业。

def clean(self): 
     workshop = self.cleaned_data.get('workshop') 
     overlaping = Workshop.objects.filter('start_time__gt'=workshop.end_time,\ 
            'start_time'=workshop.start_time).exists() 
     if overlaping: 
       raise ValidationError("Workshop times overlap.") 
     return self.cleaned_data 
1

所有概念化的第一个也不是很清楚,对于初学者应该也不能称为RegisteredUsers代替Registration(这是动词而不是名词),如果workshop是多到很多领域也许应因其保存多个条目而被命名为workshops。除此之外,你的问题是可以解决这样的:

1)在清洁workshop = self.cleaned_data.get('workshop'),它可以(可能是)多值返回到车间,让在workshops这样workshops = self.cleaned_data.get('workshops') 2)迭代将其重命名,您的查询应检查3种不同类型的重叠,一种是当有问题的工作坊完全包含在一个或多个其他此类工作坊中时,第二种是当工作坊在一个或多个工作坊之后开始但在其之前完成时,以及第三次在其他时间之前开始时研讨会,但完成后,其中一个或多个,如下所示:

from django.db.models import Q 
    for workshop in workshops: 
     if (workshops.filter(Q(start_time__gte=workshop__start_time),Q(end_time__lte=workshop__end_time) | 
          Q(start_time__lte=workshop__start_time),Q(end_time__gte=workshop__start_time)| 
          Q(start_time__lte=workshop__start_time),Q(end_time__gte=workshop__start_time)).count()>1): # count>1 is used because one of the result of filter will be the same workshop object that we are checking against 
      #there is an overlap, put your overlap handling code here 
     else: 
      #there is no overlap, put your saving the data code here 

唯一的假设h ere是研讨会是一个查询集而不是一个列表,以防其列表通过收集列表中所有研讨会的ID并将其转换回查询集,并获得研讨会的查询集:

workshops = Workshop.objects.filter(pk__in=list_of_ids)