Django- रेस्ट-फ्रेमवर्क धारावाहिकों के साथ एक विदेशी कुंजी मूल्य प्राप्त करना


89

मैं एपीआई बनाने के लिए django बाकी ढांचे का उपयोग कर रहा हूं। मेरे पास निम्न मॉडल हैं:

class Category(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class Item(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, related_name='items')

    def __unicode__(self):
        return self.name

उन श्रेणियों के लिए एक धारावाहिक बनाने के लिए जो मैं करूँगा:

class CategorySerializer(serializers.ModelSerializer):
    items = serializers.RelatedField(many=True)

    class Meta:
        model = Category

... और यह मुझे प्रदान करेगा:

[{'items': [u'Item 1', u'Item 2', u'Item 3'], u'id': 1, 'name': u'Cat 1'},
 {'items': [u'Item 4', u'Item 5', u'Item 6'], u'id': 2, 'name': u'Cat 2'},
 {'items': [u'Item 7', u'Item 8', u'Item 9'], u'id': 3, 'name': u'Cat 3'}]

मैं एक आइटम धारावाहिक से रिवर्स प्राप्त करने के बारे में कैसे जाऊँगा, अर्थात:

[{u'id': 1, 'name': 'Item 1', 'category_name': u'Cat 1'},
{u'id': 2, 'name': 'Item 2', 'category_name': u'Cat 1'},
{u'id': 3, 'name': 'Item 3', 'category_name': u'Cat 1'},
{u'id': 4, 'name': 'Item 4', 'category_name': u'Cat 2'},
{u'id': 5, 'name': 'Item 5', 'category_name': u'Cat 2'},
{u'id': 6, 'name': 'Item 6', 'category_name': u'Cat 2'},
{u'id': 7, 'name': 'Item 7', 'category_name': u'Cat 3'},
{u'id': 8, 'name': 'Item 8', 'category_name': u'Cat 3'},
{u'id': 9, 'name': 'Item 9', 'category_name': u'Cat 3'}]

मैंने डॉक्स के माध्यम से बाकी ढांचे के लिए रिवर्स रिलेशनशिप पर पढ़ा है लेकिन यह गैर-रिवर्स फ़ील्ड के समान परिणाम प्रतीत होता है। क्या मुझसे साफ़ - साफ़ कुछ चीज़ चूक रही है?

जवाबों:


85

बस सेटिंग के बिना संबंधित फ़ील्ड का उपयोग करें many=True।

ध्यान दें कि क्योंकि आप नामांकित आउटपुट चाहते हैं category_name, लेकिन वास्तविक फ़ील्ड है category, तो आपको sourceक्रमिक फ़ील्ड पर तर्क का उपयोग करने की आवश्यकता है ।

निम्नलिखित आपको आपको आवश्यक आउटपुट देना चाहिए ...

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.RelatedField(source='category', read_only=True)

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

21
कैटागरी मॉडल के सभी क्षेत्रों को पुनः प्राप्त करने के बारे में क्या ??
— एजे

12
यदि आप श्रेणी मॉडल के सभी क्षेत्रों को पुनः प्राप्त करना चाहते हैं, तो श्रेणी को क्रमबद्ध करें और इसे
— श्रेणी_नाम

7
मैंने ऐसा करने की कोशिश की, लेकिन मुझे एक त्रुटि मिल रही है Relational field must provide a 'queryset' argument, or set read_only='True'
— ePascoal

या यदि आप बनाना / अपडेट करना चाहते हैं, तो कुछ क्वेरी विशेषता प्रदान करना, जैसे: category_name = serializers.RelatedField(source='category', queryset=Category.objects.all()) मुझे लगता है।
— १

1
यदि आपको AssertionError:...इस उत्तर का उपयोग करना है stackoverflow.com/a/44530606/5403449
— जोश

86

डीआरएफ संस्करण 3.6.3 में यह मेरे लिए काम करता है

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name')

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

अधिक जानकारी यहां पाई जा सकती है: सीरीलाइज़र फ़ील्ड्स मूल तर्क


लेकिन आपको वेयरहाउस होना चाहिए क्योंकि किसी भी प्रकार की त्रुटि नहीं होनी चाहिए अगर श्रेणी फ़ील्ड आइटम मॉडल में रिक्त = True
— डेजर्ट कैमल

29

एक और चीज जो आप कर सकते हैं:

  • अपने Itemमॉडल में एक प्रॉपर्टी बनाएं जो श्रेणी का नाम और
  • इसे एक के रूप में उजागर करें ReadOnlyField।

आपका मॉडल इस तरह दिखेगा।

class Item(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, related_name='items')

    def __unicode__(self):
        return self.name

    @property
    def category_name(self):
        return self.category.name

आपका धारावाहिक ऐसा दिखेगा। ध्यान दें कि धारावाहिक बनाने वाले को category_nameउसी नाम के साथ फ़ील्ड का नाम देकर मॉडल संपत्ति का मूल्य स्वचालित रूप से मिल जाएगा ।

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField()

    class Meta:
        model = Item

18

यह मेरे लिए ठीक काम किया:

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')
    class Meta:
        model = Item
        fields = "__all__"

9

08/08/2018 और DRF संस्करण 3.8.2 पर काम किया गया:

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')

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

मेटा का उपयोग करके read_only_fieldsहम ठीक से घोषणा कर सकते हैं कि कौन से फ़ील्ड रीड_ऑनली होने चाहिए। फिर हमें foreignमेटा पर क्षेत्र को घोषित करने की आवश्यकता है fields(मंत्र स्पष्ट हो जाने के कारण बेहतर होगा: अजगर का ज़ेन )।


6

सरल समाधान source='category.name'जहां categoryविदेशी कुंजी है और .nameयह विशेषता है।

from rest_framework.serializers import ModelSerializer, ReadOnlyField
from my_app.models import Item

class ItemSerializer(ModelSerializer):
    category_name = ReadOnlyField(source='category.name')

    class Meta:
        model = Item
        fields = "__all__"

0

स्रोत मॉडल को परिभाषित करने की आवश्यकता नहीं होने के कारण यह समाधान बेहतर है। लेकिन सीरियलाइज़र फ़ील्ड का नाम विदेशी कुंजी फ़ील्ड नाम के समान होना चाहिए

class ItemSerializer(serializers.ModelSerializer):
    category = serializers.SlugRelatedField(read_only=True, slug_field='title')

    class Meta:
        model = Item
        fields = ('id', 'name', 'category')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.