J'ai lu que les importations circulaires sont une «odeur de code» et sont fondamentalement un mauvais choix de conception. J'ai une application qui a des modèles, utilisateur, Deck, Hand. Je veux que l'utilisateur soit capable de créer une main sans avoir besoin de créer une plate-forme, mais donne également à l'utilisateur le choix de mettre la main dans la plate-forme si désiré. Donc, je me retrouve avec quelque chose comme ceci:Comment créer "proprement" cette relation de sérialisation Django/DRF entre modèles?
(< signifie ForeignKey relation)
utilisateur < Pont < main
& &
utilisateur < Pont
& &
utilisateur < main
models.py:
class User(AbstractUser):
pass
class Deck(models.Model):
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=100, unique=True,
blank=False, null=False)
user = models.ForeignKey('users.User', related_name='decks',
on_delete=models.CASCADE, null=False)
class Hand(models.Model):
created = models.DateTimeField(auto_now_add=True)
deck = models.ForeignKey('goals.Deck', related_name='hands', on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100, blank=False, null=False)
user = models.ForeignKey('users.User', related_name='hands', on_delete=models.CASCADE, null=False)
serializers.py:
class HandSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
deck = serializers.CharField(required=False, source='deck.name')
class Meta:
model = Hand
fields = ('url', 'id', 'created',
'deck', 'name', 'user')
extra_kwargs = {
'url': {
'view_name': 'goals:hand-detail',
}
}
class DeckSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
hands = HandSerializer(many=True, read_only=True)
class Meta:
model = Deck
fields = ('url', 'id', 'created', 'name', 'user')
extra_kwargs = {
'url': {
'view_name': 'goals:deck-detail',
}
}
class UserSerializer(serializers.HyperlinkedModelSerializer):
decks = DeckSerializer(many=True)
hands = HandSerializer(many=True)
...
Est-ce la bonne approche-sage API-conception afin d'obtenir ce que je veux application -conception-sage? Sinon, comment dois-je faire cela? Et si oui, comment contourner les erreurs d'importation circulaires lorsque je change d'utilisateur d'un champ ReadOnlyField à un champ UserSerializer()?
Edit:
Je pensais si cette approche était mauvaise, voire impossible, avec les importations circulaires, je pouvais créer une relation standard d'une façon comme:
utilisateur -> Pont -> main
et d'avoir une Deck par défaut cachée à l'utilisateur afin que l'Utilisateur puisse toujours créer une Main sans créer sa propre Deck car elle a déjà été faite par défaut (juste cachée). Mais cela ressemble à un hack aussi et je ne sais pas si cette approche sent plus que l'initiale.