Python 如何“干净地”在模型之间创建这种Django/DRF序列化关系?
我读过,循环导入是一种“代码气味”,从根本上说是一种糟糕的设计选择。我有一个应用程序,有模型,用户,甲板,手。我希望用户能够创建一只手,而无需创建一副牌,但如果需要,还可以让用户选择将手放在牌组中。所以我的结局是这样的: <表示外键关系 用户<甲板<手 && 用户Python 如何“干净地”在模型之间创建这种Django/DRF序列化关系?,python,django,serialization,django-rest-framework,api-design,Python,Django,Serialization,Django Rest Framework,Api Design,我读过,循环导入是一种“代码气味”,从根本上说是一种糟糕的设计选择。我有一个应用程序,有模型,用户,甲板,手。我希望用户能够创建一只手,而无需创建一副牌,但如果需要,还可以让用户选择将手放在牌组中。所以我的结局是这样的:
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字段时,如何避免循环导入错误
编辑:
我在想,如果这种方法对循环进口不好或不可能,我可以创建一种标准的单向关系,如:
用户->甲板->手
并且有一个对用户隐藏的默认牌组,这样用户仍然可以创建手牌,而无需创建他/她自己的牌组,因为默认情况下,它已经被隐藏了。但这感觉也像是一种黑客行为,我不知道这种方法是否比最初闻起来更难闻。这是正确的。假设我想请求ID为1的帮助。我会对/api/hands/1执行GET请求,对吗?我真的希望它用一个用户的全部双手序列化一个完整的用户吗?大概这要看情况而定 要绕过它,您可以定义如下内容: 最小用户序列化程序 -仅返回电子邮件、用户名和ID。 -不回手。 您将使用它,而不是始终返回hands的完整UserSerializer