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.