Создание другого объекта при создании объекта в модели 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, чтобы обновить их.

Вернуться на верх