简体   繁体   English

在Django中通过管理网站添加对象时出错

[英]Error while adding objects via admin site in django

I've created the following models: 我创建了以下模型:

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',)})

Generally, I'd like to avoid overlaping time in specified days when adding instances of RentPeriod via admin site. 通常,通过管理网站添加RentPeriod实例时,我希望避免在指定的几天出现时间重叠 When I try to add RentPeriod instance, I get following error: 当我尝试添加RentPeriod实例时,出现以下错误:

'' needs to have a value for field "rentperiod" before this many-to-many relationship can be used. 在使用这种多对多关系之前,“”需要具有字段“ rentperiod”的值。

I've read click , but I don't have idea how to get it to work. 我已经阅读了click ,但是我不知道如何使它起作用。 Could you help? 你能帮忙吗?

Attention: complexity (n^2) has no matter in this case. 注意:在这种情况下,复杂度(n ^ 2)无关紧要。

UPDATE I've created custom validator according to 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

and admin.py 和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

Unfortunately, own validator "is not called" - I mean even test ValidationError is not raising. 不幸的是,自己的验证器“没有被调用”-我的意思是即使测试ValidationError也没有提高。

UPDATE 2 Figuret out that it was problem with "register" statement. UPDATE 2弄清楚“ register”语句存在问题。 It should be: 它应该是:

admin.site.register(RentPeriod, RentPeriodAdmin)

I would suggest that validate_unique on the model would NOT be the place to do this. 我建议不要在模型上使用validate_unique。

To do this level of validation you need the model to have a PK, but in order to have a PK it needs to be saved to DB, but in order to save to DB it needs to validate. 要进行此级别的验证,您需要模型具有PK,但是要拥有PK,则需要将其保存到DB,但是要保存到DB,则需要进行验证。 See the problem? 看到问题了吗?

You would need to move this kind of validation into the form/formset. 您将需要将这种验证移至表单/表单集中。 This means overloading the clean() method of the InlineFormset that I assume your using for input of hours. 这意味着重载了我假设您用于输入小时数的InlineFormset的clean()方法。 Ref: Inline Form Validation in Django 参考: Django中的内联表单验证

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM