Я создал следующие модели:Ошибка при добавлении объектов через администратора сайта в Джанго
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)
Да, я вижу проблему. Я создал специальный валидатор. Есть ли разница в том, как я добавил валидатор и использовал InlineFormset? Я также пытался использовать InlineFormset, но проверка не была вызвана. – 2013-04-02 10:26:30
ОК, выяснилось, что проблема была неправильной. – 2013-04-02 18:56:24