Создание другого объекта при создании объекта в модели django
Когда я создаю объект типа:
bus_stop_1 = 4(Foreign Key)
bus_stop_2 = 7
, то он должен автоматически создать другой объект с
bus_stop_1 = 7
bus_stop_2 = 4
** Время и расстояние будут одинаковыми ** BusStop - это модель Моя модель
class ConnectedRoute(models.Model):
bus_stop_1 = models.ForeignKey(
BusStop, on_delete=models.CASCADE, related_name='stop1')
bus_stop_2 = models.ForeignKey(
BusStop, on_delete=models.CASCADE, related_name='stop2')
distance = models.FloatField(blank=True, null=True)
time = models.TimeField(blank=True, null=True)
Я пробовал это сделать, используя метод save и сохраняя ConnectedRoute, но он вызывается рекурсивно снова и снова.
def save(self, *args, **kwargs):
# Check if the object is being created for the first time
if not self.pk:
# Create a new ConnectedRoute object with reversed bus stops
reverse_connected_route = ConnectedRoute(
bus_stop_1=self.bus_stop_2,
bus_stop_2=self.bus_stop_1,
distance=self.distance,
time=self.time
)
reverse_connected_route.save() # Save the reversed object
super().save(*args, **kwargs)
Вы должны использовать .get_or_create
- он создает новый экземпляр, только если он не существует, вот так:
reverse_connected_route, created = ConnectedRoute.objects.get_or_create(
bus_stop_1=self.bus_stop_2,
bus_stop_2=self.bus_stop_1,
)
if (reverse_connected_route.distance, reverse_connected_route.time) != (self.distance, self.time):
reverse_connected_route.distance = self.distance
reverse_connected_route.time = self.time
reverse_connected_route.save(update_fields=['distance', 'time'])
Этот оператор if предотвратит рекурсивные вызовы.
Возможно, вам нужно будет переместить super().save()
на самый верх
Другой способ - использовать сигналы db, например, так:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=ConnectedRoute)
def trigger_reverse_route_creation(sender, instance, **kwargs):
if kwargs['created'] == True:
sender.objects.get_or_create(
bus_stop_1=instance.bus_stop_2,
bus_stop_2=instance.bus_stop_1,
defaults={'distance': instance.distance, 'time': instance.time}
)
Но такой подход не позволит обновить расстояние и время второго маршрута, если первый был обновлен. Придется добавить сюда аналогичный оператор if
, чтобы обновить их.