Извинения, если на этот вопрос уже был дан ответ, но он искал часы.
Я пытаюсь выполнить проверку на модели отдыха Джанго с полем m2m. У меня есть модель, которой назначены роли. У меня есть логика, если роли перекрываются с существующими моделями и хотели бы выдать ошибку проверки. Я пробовал сигнал pre_save, но, видимо, django не назначает m2m до тех пор, пока не сохранится (без идентификатора). Как мне получить доступ к данным pre_save? Вот модель:
class ActivityFactory (models.Model):
"""
This provides an interval over which ActivityDemands are auto-generated and ActivityStudyHours (note that activity study hours can be obsolete as all of the same information is already stored here) instead of the traditional method of inputing ActivityDemands per month. The product of Activity and ActivityDemand will still create StudySiteWorkloads.
"""
start_date = models.DateField()
end_date = models.DateField()
hours = models.DecimalField(max_digits=5, decimal_places=2)
notes = models.TextField(blank=True, null=True)
activity = models.ForeignKey(Activity, on_delete=models.CASCADE, related_name='activity_factories')
roles = models.ManyToManyField(Role, blank=True, related_name='activity_factories')
study = models.ForeignKey(Study, on_delete=models.CASCADE, related_name="activity_factories")
trend_curve = models.ForeignKey(TrendCurve, on_delete=models.CASCADE, related_name="activity_factories")
slug = AutoSlugField(populate_from='study', db_index=True, unique=True, null=True)
class Meta:
verbose_name_plural = 'Activity Factories'
def __str__(self):
return "%s: %s : %s" % (self.study.study_name, self.activity.activity_name, self.trend_curve.denominator_name)
Вот предварительное сохранение:
@receiver(pre_save, sender=ActivityFactory)
def validate_factory(sender, instance, **kwargs):
queryset = ActivityFactory.objects.filter(activity=instance.activity, study=instance.study)
roles=instance.roles.objects.all()
for activity_factory in queryset:
if activity_factory.slug!=instance.slug:
if ((activity_factory.start_date <= instance.start_date <= activity_factory.end_date) or (activity_factory.start_date >= instance.end_date >= activity_factory.end_date)) and bool(set(activity_factory.roles.all()) & set(roles)):
raise serializers.ValidationError({'activity':'Date intervals cannot overlap for a given activity in the same study with the same assigned role'}, code=400)
if activity_factory.activity==instance.activity and activity_factory.hours!=instance.hours and bool(set(activity_factory.roles.all()) & set(roles)):
raise serializers.ValidationError({'activity':'The same activity can not have differing hours assigned to the same role within a study. Consider a new activity or keep hours the same'}, code=400)