我读过的圆形进口是一个“代码味道”,是从根本上坏的设计选择。我有一个应用程序,有模型,用户,甲板,手。我希望用户能够创建一个手而不需要创建一个甲板,但如果需要,也可以让用户选择将手放在甲板上。所以,我最终是这样的:如何'干净地'在模型之间创建这个Django/DRF序列化关系?
(<意味着ForeignKey的关系)
用户<甲板<手
& &
用户<甲板
& &
用户<手
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)
...
这是正确的做法API设计明智,以达到我想要的应用程序 - 设计明智?如果不是,我该如何去做这件事?如果是这样,当我将用户从ReadOnlyField更改为UserSerializer()字段时,如何解决循环导入错误?
编辑:
我就在想,如果这种做法是不好的或不可能的圆形进口,我可以创建像一个标准的单向关系:
用户 - >甲板 - >手
,并会有从用户隐藏起来,用户仍然可以创建一个没有手,因为它已经被默认创建完成他/她自己的甲板(只是隐藏起来),默认的甲板。但是这种感觉也像是一种黑客,我不知道这种方法是否比最初的方法更有味道。