Я хотел бы получить совет относительно архитектурной проблемы, с которой я сталкивался много раз. У меня есть Событие модели в events.py:
# models.py
import events.serializers
class Event(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, db_index=True)
...
def save(self, *args, **kwargs):
is_new = not self.pk
super().save(*args, **kwargs)
if is_new:
self.notify_organiser_followers()
def notify_organiser_followers(self):
if self.organiser:
event_data = events.serializers.BaseEventSerializer(self).data
payload = {'title': f'New event by {self.organiser.name}',
'body': f'{self.organiser.name} has just created a new event: {self.name}',
'data': {'event': event_data}}
send_fcm_messages(self.organiser.followers.all(), payload)
В модели есть сериализатор BaseEventSerializer. В методе сохранения я использую notify_organiser_followers и в процессе сериализации текущего сохраняемого события. Для этого мне нужно импортировать BaseEventSerializer.
Вот как выглядит код events.serializers:
# serializers.py
import events.models
class EventTrackSerializer(serializers.ModelSerializer):
class Meta:
model = events.models.EventTrack
fields = ('id', 'name', 'color')
class BaseEventSerializer(serializers.ModelSerializer):
event_type = serializers.CharField(source='get_event_type_display')
locations = serializers.SerializerMethodField()
Как вы видите, serializers.py должен импортировать модели, чтобы использовать их в ModelSerializer. На этом этапе я получаю очевидный циклический импорт.
Я решил это путем локального импорта BaseEventSerializer в функцию notify_organiser_followers:
def notify_organiser_followers(self):
if self.organiser:
from events.serializers import BaseEventSerializer
Это устраняет проблему, но я Я бы очень хотел избежать этого, особенно потому, что мне пришлось бы делать одно и то же исправление в нескольких местах моего репо. Другой подход, о котором я подумал, - разделить «обычные» сериализаторы и сериализаторы моделей на отдельные файлы. Тем не менее, кажется, что это только исцеление симптома, а не причины.
Мне хотелось бы получить совет о том, как вообще избежать этой ситуации. У меня была такая же проблема при импорте двух разных приложений, которые используют сериализатор друг друга. Например, Пользователь сериализует События, которые он посещает, Событие сериализует своих посетителей. Как бы вы go о разъединении этих двух моделей? Кажется, что модельные отношения часто вынуждают меня в такие ситуации, и избегать циклического импорта становится действительно сложно.
Я также был бы признателен, если бы у вас были какие-либо более крупные проекты Django / DRF Github, демонстрирующие, как этого избежать, поскольку эта проблема постоянно возникает для меня, как только мое приложение станет достаточно большим.