2017-02-18 12 views
2

私のアプリケーションではいくつかの製品があり、ログインしたユーザーはこれらの製品をお気に入りとしてマークできます。Django Rest Frameworkの多対多リレーションシップのユーザー依存フィールド

私はこのように、私のmodels.pyの多くの関係に多く、それらをモデル化:私は今、達成したい何

class Product(models.Model): 
    product_name = models.CharField(max_length=200) 
    # ... 


    def __unicode__(self): 
     return self.product_name 


class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    favorites = models.ManyToManyField(Product) 

    @receiver(post_save, sender=User) 
    def create_user_profile(sender, instance, created, **kwargs): 
     if created: 
      Profile.objects.get_or_create(user=instance) 

    @receiver(post_save, sender=User) 
    def save_user_profile(sender, instance, **kwargs): 
     instance.profile.save() 

製品がある場合、製品の詳細ビューにユーザーが見ることができるということですすでに彼のお気に入りであり、ボックスをチェックして彼のお気に入りにすることができるはずです。

これは多対多リレーションシップですが、ビュー上ではブーリアンリレーションシップ(現在のユーザーにとって好きなはい/いいえ)です。

私はすでに私は現在のように、このセットアップでお気に入りの現在のユーザーのリストにお気に入りを追加しているに苦しんでいますどのようなSerializerMethodField

class ProductSerializer(serializers.ModelSerializer): 
    # ... 
    favorite = serializers.SerializerMethodField() 

    def get_favorite(self, obj): 
    try: 
     self.context['request'].user.profile.favorites.get(pk=obj.pk) 
     return True 
    except Product.DoesNotExist: 
     return False 

で、詳細ビューに表示されるの好きな地位を持っているために管理このSerializerMethodFieldは読み取り専用であるため、update()メソッドのvalidated_dataには表示されません。

誰かがこれまたは同様の問題の解決策を持っていますか?

答えて

1

カスタムフィールドを作成することができます。

class FavoriteField(serializers.BooleanField): 

    def get_attribute(self, instance): 
     return self.context['request'].user.profile.favorites.filter(pk=instance.pk).exists() 

class ProductSerializer(serializers.ModelSerializer): 
    favorite = FavoriteField() 

    def update(self, instance, validated_data): 
     instance = super().update(instance, validated_data) 
     is_favourite = validated_data.get('favorite') # can be None 
     if is_favourite is True: 
      self.context['request'].user.profile.favorites.add(instance) 
     elif is_favourite is False: 
      self.context['request'].user.profile.favorites.remove(instance) 
     return instance 
+0

それは魅力的なように機能しました、私を助けてくれてありがとう! –

+1

@ R.Wenger YW。ところで、 'favorites.add'と' favorites.remove'はdjangoが内部的に作ったものなので、追加のチェックをせずに呼び出すことができます。 – Raz

+0

それを知らなかった、もう一度ありがとう! –

関連する問題