2013-04-01 4 views
1

Я создал следующие модели:Ошибка при добавлении объектов через администратора сайта в Джанго

class BasePrice(models.Model): 
     start_hour = models.TimeField(blank=False) 
     end_hour = models.TimeField(blank=False) 
     monday = models.BooleanField(blank=False) 
     tuesday = models.BooleanField(blank=False) 
     wednesday = models.BooleanField(blank=False) 
     thursday = models.BooleanField(blank=False) 
     friday = models.BooleanField(blank=False) 
     price = models.IntegerField(blank=False) 

     def __unicode__(self): 

      days = "" 

      if (self.monday == True): 
       days = days + " Mon" 
      if (self.tuesday == True): 
       days = days + " Tue" 
      if (self.wednesday == True): 
       days = days + " Wed" 
      if (self.thursday == True): 
       days = days + " Thu" 
      if (self.friday == True): 
       days = days + " Fri" 
      return "Price " + str(self.price) + " at " + str(self.start_hour) + ":" +str(self.end_hour) + " in " + days 

    def clean(self): 

     if self.start_hour > self.end_hour: 
      raise ValidationError('Start hour is older than end hour!') 

class RentPeriod(models.Model): 
    start_date = models.DateField(blank=False) 
    end_date = models.DateField(blank=False) 
    desk = models.ForeignKey(Desk) 
    base_prices = models.ManyToManyField(BasePrice) 

    def __unicode__(self): 
     return "Period " + str(self.start_date) + " to " + str(self.end_date) + " for " + self.desk.__unicode__() 

    def clean(self): 

     if self.start_date > self.end_date: 
      raise ValidationError('Start date is older than end date!') 

    def validate_unique(self, *args, **kwargs): 
     super(RentPeriod, self).validate_unique(*args, **kwargs) 
    # overlaping hours 
     basePrices = self.base_prices.all() 

     for price in basePrices: 
      qs = self.__class__._default_manager.filter(
       (Q(monday=True) & Q(monday=price.monday)) | 
       (Q(tuesday=True) & Q(tuesday=price.tuesday)) | 
       (Q(wednesday=True) & Q(wednesday=price.wednesday)) | 
       (Q(thursday=True) & Q(thursday=price.thursday)) | 
       (Q(friday=True) & Q(friday=price.friday)), 
       start_hour__lte=self.end_hour, 
       end_hour__gte=self.start_hour 
      ) 

      if qs.exists(): 
       raise ValidationError({NON_FIELD_ERRORS: ('overlaping hours range',)}) 

Вообще, я хотел бы избежать перекрывающихся время в определенные дни при добавлении экземпляров RentPeriod через администратора сайта. Когда я пытаюсь добавить экземпляр RentPeriod, я получаю следующее сообщение об ошибке:

'' needs to have a value for field "rentperiod" before this many-to-many relationship can be used.

Я прочитал click, но я не знаю, как заставить его работать. Не могли бы вы помочь?

Внимание: сложность (n^2) не имеет значения в этом случае.

UPDATE Я создал пользовательский валидатор согласно documentation

forms.py

from biurrko.rents.models import RentPeriod 
from django.forms.models import ModelForm 

class RentPeriodForm(ModelForm): 
    class Meta: 
     model = RentPeriod 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     basePrices = cleaned_data['base_prices'] 
     end_hour = cleaned_data['end_hour'] 
     start_hour = cleaned_data['start_hour'] 

     for price in basePrices: 
      qs = basePrices.filter(
       (Q(monday=True) & Q(monday=price.monday)) | 
       (Q(tuesday=True) & Q(tuesday=price.tuesday)) | 
       (Q(wednesday=True) & Q(wednesday=price.wednesday)) | 
       (Q(thursday=True) & Q(thursday=price.thursday)) | 
       (Q(friday=True) & Q(friday=price.friday)), 
       start_hour__lte=end_hour, 
       end_hour__gte=start_hour 
      ) 

      if qs.exists(): 
       raise ValidationError({NON_FIELD_ERRORS: ('overlaping hours range',)}) 

     # only for test 
     raise ValidationError({NON_FIELD_ERRORS: ('reached',)}) 
     # return cleaned_data 

и admin.py

from django.contrib import admin 
from biurrko.rents.models import Desk, Room, RentPeriod, BasePrice 
from biurrko.rents.forms import RentPeriodForm 

admin.site.register(Desk) 
admin.site.register(Room) 
admin.site.register(RentPeriod) 
admin.site.register(BasePrice) 


class RentPeriodAdmin(admin.ModelAdmin): 
    form = RentPeriodForm 

К сожалению, собственный валидатор «не называется «Я имею в виду даже тест ValidationError не поднимает.

UPDATE 2 Figuret, что это была проблема с "регистром" заявления. Оно должно быть:

admin.site.register(RentPeriod, RentPeriodAdmin) 

ответ

0

Я хотел бы предложить, что validate_unique на модели не было бы место, чтобы сделать это.

Чтобы сделать этот уровень проверки, вам нужна модель для ПК, но для того, чтобы иметь ПК, ее нужно сохранить в БД, но для того, чтобы сохранить ее в БД, ее необходимо проверить. См. Проблему?

Вам нужно будет переместить этот вид проверки в форму/набор форм. Это означает перегрузку метода clean() InlineFormset, который я предполагаю использовать для ввода часов. Ref: Inline Form Validation in Django

+0

Да, я вижу проблему. Я создал специальный валидатор. Есть ли разница в том, как я добавил валидатор и использовал InlineFormset? Я также пытался использовать InlineFormset, но проверка не была вызвана. – 2013-04-02 10:26:30

+0

ОК, выяснилось, что проблема была неправильной. – 2013-04-02 18:56:24

Смежные вопросы