【问题标题】:Unable to use perform_create to make a reverse relationship between two model无法使用 perform_create 在两个模型之间建立反向关系
【发布时间】:2017-06-18 20:53:57
【问题描述】:

我有三个模型,"Item" 、 "Seller" 和 "User"User 就像管理员一样,他可以创建 Seller,每个 Seller 都会有一个唯一的 id,假设为“uid”。 而 User 创建的 Sellers 可以创建 Item ,所以我想制作一个 API,如果 Seller 创建/posts a new Item ,我想要(用户和卖家)和(卖家和物品)之间的反向关系。即用户创建的每个卖家都应该有一个包含他创建的所有卖家的字段。每个卖家都应该有一个文件,告诉创建它的用户的名字。卖家和商品之间的相似性。每个卖家都会有他创建的商品列表,并且每个商品都会有一个提交的卖家创建它。

现在我已经实施了用户和卖家反向关系,但我无法创建卖家和商品反向关系。我关注了这些链接Tutorial 4: Authentication & PermissionsSerializer relations。 这是我的代码 sn-p :

模型.py

class Seller(models.Model):
 UID=models.CharField(max_length=50,unique=True)
 name=models.CharField(max_length=100)
 ....
 super_owner = models.ForeignKey('auth.User', related_name='seller_added') 

 def __unicode__(self):
    return '%s'  (self.UID)

class Item(models.Model):
 name=models.CharField(max_length=250)
 ....
 seller_uid= models.ForeignKey(Seller,related_name='items_added', on_delete=models.CASCADE)


 def __unicode__(self):
 return '%s: %d' % (self.name, self.mrp)

序列化器.py

class UserSerializer(serializers.ModelSerializer):
 seller_added = serializers.PrimaryKeyRelatedField(many=True, queryset=Seller.objects.all()) 
 class Meta:
 model = User
 fields = ('id', 'username','seller_added')


class SellerSerializer(serializers.ModelSerializer):
 items_added = serializers.StringRelatedField(many=True) 
 super_owner = serializers.ReadOnlyField(source='super_owner.username')  


  class Meta:
   model = Seller
   fields = ('UID','name','items_added','super_owner')


class ItemSerializer(serializers.ModelSerializer):

 seller_uid= serializers.ReadOnlyField(source='seller_uid.UID') 

  class Meta:
   model = Item
   fields = ('id', 'name', 'seller_uid')

Views.py

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    This viewset automatically provides `list` and `detail` actions.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly_seller,)



    def perform_create(self, serializer):
        serializer.save(seller_uid=self.request.user.seller_uid)    


class SellerViewSet(viewsets.ModelViewSet):
    queryset = Seller.objects.all()
    serializer_class = SellerSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,

    def perform_create(self, serializer):
        serializer.save(super_owner=self.request.user)  

不知道ItemViewSet的perform_create应该写什么??Seller 模型中,归档的 super_owner 是通过使用 super_owner=self.request.user 从方法 perfom_create 初始化的。同样,我想初始化在 Item 模型中声明的归档 seller_uid。从 ItemSerializer seller_uid=serializers.ReadOnlyField(source='seller_uid.UID') 中删除此行并从 SellerViewSet 中删除 perform_create。我的 api 有效,但是当我发布它时,它要求选择我想用作外键的 Seller。但我想自动做这件事。如 super_owner 的情况。简单来说应该在ItemViewSetperform_create中写什么来直接设置seller_uid
任何帮助将不胜感激。

【问题讨论】:

    标签: api relational-database foreign-key-relationship django-rest-framework


    【解决方案1】:

    你的问题是super_owner 写在ReadOnlyField 所以你的序列化器不会读取它。只需删除该字段并使用默认字段即可。现在您可以向它发送user.id,也可以删除perform_create
    如果你想要一个特殊的表示,虽然你可以覆盖to_representation serializers 方法:

    class SellerSerializer(serializers.ModelSerializer):
        items_added = serializers.StringRelatedField(many=True) 
    
        class Meta:
            model = Seller
            fields = ('UID','name','items_added','super_owner')
    
        def to_representation(self, instance):
            representation = super(SellerSerializer, self).to_representation(instance)
            representation['super_owner'] = instance.super_owner.username
            return representation
    

    【讨论】:

    • 嗨,谢谢你的回答。它帮助了我一些其他的方式。但我的问题是另外一回事。在 Seller 模型中,归档的 super_owner 是通过使用 super_owner=self.request.user 从方法 perfom_create 初始化的。同样,我想初始化在项目模型中声明的卖家uid 的字段。通过删除 Seller_uid= serializers.ReadOnlyField(source='seller_uid.UID')
    • @BhupendraSinghChauhan 对不起,我不明白你的问题,你想创建一个从 Seller 模型到 Item 的链接吗?还是在创建Seller 时创建Item?在第一种情况下,您可以删除StringRelatedField 并在字段中写入items_added,这样您就可以将ids 传递给Itemitems_added 字段。如果要创建Item,则应在Seller serizlier 中重写create 方法或将该逻辑移动到Seller manager 中,这是创建两个相关模型的常用方法。
    • 对不起,我已经编辑了我的问题。我想现在会很清楚了。我想链接卖家和商品。谢谢
    • @BhupendraSinghChauhan 那么问题来了领域?
    • 是的,我已经删除了这一行。在此之后,当我使用 item api 时,它有一个 Seller_uid 属性,现在我必须从所有创建的卖家的下拉列表中选择,我想选择作为外键的卖家。所以我怀疑是,如果使用这个 api 从某个应用程序发出一个帖子请求。我是否必须正常设置seller_uid,因为Item 中的所有其他属性都是可编辑/可写的,但seller_uid 有一个下拉菜单。 @ivan
    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 2012-05-08
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多