세 가지 모델이 있습니다. 첫 번째는 DayOfWeek라고하는데, 이는 하루 레이블과 번호입니다. 그것은 다음과 같습니다Django Many To Many PrimaryKey에 대해 불평 함
class DayOfWeek(models.Model):
day = models.IntegerField()
label = models.CharField(max_length='20')
def __str__(self):
return self.label
이 클래스는 다음과 같다, 내가 syncdb.Next 때마다, 나는 이벤트 모델이 고정물을 사용하여 채워집니다
마지막으로class Event(AnnouncementBase, Location):
cost = CurrencyField(decimal_places=2, max_digits=10, blank=True, default=0.00)
start_date = models.DateField(default = datetime.now().date())
start_time = models.TimeField(default = datetime.now().time())
end_date = models.DateField(blank=True, default=None, null = True)
end_time = models.TimeField(blank=True, default=None, null = True)
은 재발이 . 이벤트가 있으며 반복 이벤트에 대한 이벤트를 예약하는 데 사용됩니다. 그것은 다음과 같습니다
class Recurrence(models.Model):
event = models.ForeignKey(Event, related_name='event')
repeats = models.CharField(max_length = 50, choices = EVENT_REPEAT_CHOICES)
repeat_every = models.IntegerField(default = 1)
repeat_on = models.ManyToManyField(DayOfWeek, blank=True, null=True)
repeat_by = models.CharField(max_length = 50, choices = EVENT_REPEAT_BY_CHOICES, blank=True)
repeat_by_day_of_month = models.IntegerField(default = 0, blank=True)
repeat_ends = models.CharField(max_length = 50, choices = EVENT_REPEAT_END_CHOICES)
end_occurrences = models.IntegerField(default = 0, blank=True)
repeat_end_date = models.DateField(blank=True, default=None, null = True)
past_event_count = models.IntegerField(default=0, blank=True)
scheduled_events = models.ManyToManyField(Event, blank=True, default=None, related_name = 'scheduled_events')
is_active = models.BooleanField(blank=True, default=True)
def save(self, force_insert=False, force_update=False, using=None):
"""Overridden to create events the first time."""
self.full_clean()
#First do normal save so the data is there for the even scheduler.
self.save_base(force_insert=force_insert, force_update=force_update, using=using)
#If nothing is scheduled yet, schedule the first batch
if self.scheduled_events.count() == 0 and self.past_event_count == 0:
self.scheduleEvents()
def clean(self):
#repeat on weekly
if self.repeat_every < 1:
raise ValidationError('Repeat every must be at least 1.')
#weekly
if self.repeats == EVENT_REPEAT_CHOICES[1][0]:
#look for missing stuff
if not self.repeat_on:
raise ValidationError('Missing repeat on.')
마지막으로, 나는 이것이는 다음과 같습니다 확인 작동 확인하는 단위 테스트가 있습니다
테스트는 다음을 제외하고, 실패를 실행할 때마다def test_weekly_mon_wed_fri_occurrence(self):
event = Event()
event.start_date = date(year=2012, month=1, day=2)
event.start_time = time(hour=13, minute=30)
event.save()
recurrence = Recurrence()
recurrence.repeats = EVENT_REPEAT_CHOICES[1][0]
recurrence.repeat_on = (EVENT_DAY_CHOICES[1][0], EVENT_DAY_CHOICES[3][0], EVENT_DAY_CHOICES[5][0])
recurrence.repeat_ends = EVENT_REPEAT_END_CHOICES[0][0]
recurrence.event = event
nextEvent = recurrence.getNextEvent(event)
self.assertEquals(date(year=2012, month=1, day=4), nextEvent.start_date)
self.assertEquals(event.start_time, nextEvent.start_time)
nextNextEvent = recurrence.getNextEvent(nextEvent)
self.assertEquals(date(year=2012, month=1, day=6), nextNextEvent.start_date)
self.assertEquals(event.start_time, nextNextEvent.start_time)
. ValueError : '되풀이'인스턴스는 일대 다 키 값을 가져야 만 다 대다 관계를 사용할 수 있습니다.
clean 메서드에서 self.repeat_on을 사용하면 줄에 오류가 발생합니다.
repeat_on을 선택 사항으로 지정하려면 일부 재발 유형에만 필요합니다. 이 작업을 어떻게 수행합니까? 나는 그것을 놓치고 무엇이 실패하게 만들까?
아직 집에 없지만 한 가지 질문이 있습니다. 재발 호출을 저장하면 오류가 발생합니다. 또한이 오류가 발생하지 않았더라도 유효성 검사 오류를 일으킬 수 있습니다. repeat_on 값이 필요한 경우가 있습니다. repeat_on이 필요하지 않을 때 중단없이 검증하려면 어떻게해야합니까? save에 대한 첫 번째 호출은 항상 유효성을 검사하지 못합니다. – Jon
당신이 맞습니다, 그리고 이것은 장고의 M2M 관계의 한계입니다. 모델 AND 형식 모두 고유 한 클린 방법이 있음에 유의하십시오. 모델의 'clean'은 자체적으로 충분해야하며 해당 모델에있는 데이터 만 유효성을 검사해야합니다. Many2ManyField에서'through'를 사용하여 자신 만의 M2M 테이블을 구현하고 intermediery 모델에'clean'을 추가하거나 직접 외래 키를 저장하거나, 더 잘 맞을 것이라고 생각하는 경우 Form의 clean을 사용하여 전체적으로 요청의 유효성을 검사 할 수 있습니다. – astevanovic