2017-12-26 39 views
0

私のアプリケーションでDjango Rest Frameworkを使用しています。私は外部キーを含む新しいモデルインスタンスを作成する必要があります。これらは別のテーブルの既存のオブジェクトを参照するので、これらの異物の新しいインスタンスを作成することは望ましくありません。また、その情報が提出されていないので、主キーを介してこれらのオブジェクトにアクセスすることはできません(がである特定のフィールドをフィルタリングする必要があります)。Django REST Frameworkシリアライザ - 既存の外部キーへのアクセス

どうすればよいですか? This質問は同じ問題に対処しているようですが、受け入れられた答えが実際に問題を解決することは明らかではありません。カテゴリを指定し、後者でForeignKeyフィールドで、Iは、2つのモデル、CategoryItemがあると:

class Category(models.Model): 
    name = models.TextField() 
    format = models.TextField() 
    page = models.IntegerField(default=1) 
    order = models.IntegerField(default=1) 

class Item(models.Model): 
    username = models.TextField() 
    title = models.TextField() 
    category = models.ForeignKey('Category', null=True) 
    data = JSONField(null=True, blank=True) 

POSTリクエストのボディフォーマットを指定するオブジェクトとして定義されたカテゴリと、JSONペイロードから構成され、ページとオーダーフィールド:

POST /api/items 
{ 
    "username" : "test", 
    "title" : "foo", 
    "category" : { 
    "format" : "A", 
    "page" : 2, 
    "order" : 1 
    }, 
    "data" : [1,2,3,4,5] 
} 

それから私は、それが適切なフィールドにフィルタリングすることによって、右Categoryインスタンスを取得するようcreateをオーバーライドし、次のように私は私のItemシリアライザを定義できます仮定します返されたItemインスタンスに設定します。

class ItemSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 
    data = serializers.ListField() 

    class Meta: 
     model = Item 
     fields = ('username', 'title', 'category', 'data') 

    def create(self, validated_data): 
     category_dict = validated_data.pop('category') 
     item = Item.objects.create(**validated_data) 
     format = category_dict.format 
     page = category_dict.page 
     order = category_dict.order 
     item.category = Category.objects.get(format=format, page=page, order=order) 
     return item 

これは正しい方法ですか?

+1

はい、正しい方法です。名前を付ける必要があります。したがって、カテゴリにこれらの詳細が存在しない場合は、新しいカテゴリも作成できます。あなたがすでに利用可能な正しいカテゴリを与えていると確信している場合は、それを行う正しい方法です。 –

答えて

1

これは、少なくとも1つのエラーがある

try: 
    category = Category.objects.filter(format=format, page=page, order=order) 
except Category.DoesNotExist: 
    # either make it None or create new category, depends on your requirement 
    category = None 
    # or create new category 
except Category.MultipleObjectsReturned: 
    category = category.first() # it depends on your requirement 
item.category = category 
1

ようになり、あなたはquerysetを取得する代わりに使用filterのあなたのアイテムのカテゴリとして一つだけのカテゴリを取得するためにgetを使用する必要があります。

class ItemSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 
    data = serializers.ListField() 

    class Meta: 
     model = Item 
     fields = ('username', 'title', 'category', 'data') 

    def create(self, validated_data): 
     category_dict = validated_data.pop('category') 
     item = Item.objects.create(**validated_data) 
     format = category_dict.format 
     page = category_dict.page 
     order = category_dict.order 
     try: 
      item.category = Category.objects.get(format=format, page=page, order=order) 
     except Category.DoesNotExist: 
      pass 
     except Category.MultipleObjectsReturned: 
      pass 
     return item 
関連する問題