Django बाकी ढांचे को कई क्षेत्र में क्रमबद्ध करते हुए


84

मैं किसी भी चीज़ की सूची में कई-से-कई फ़ील्ड कैसे अनुक्रमित करूं, और उन्हें बाकी ढांचे के माध्यम से वापस कर दूं? नीचे दिए गए मेरे उदाहरण में, मैं इसके साथ जुड़े टैग की सूची के साथ पोस्ट को वापस करने की कोशिश करता हूं।

model.py

class post(models.Model):
    tag = models.ManyToManyField(Tag)
    text = models.CharField(max_length=100)

क्रमबद्ध करने वाला

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag"??)

विचार

class PostViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

@ ब्रायन से मदद का उपयोग करते हुए मैं इस रूप में वस्तुओं को सूचीबद्ध करने का प्रबंधन करता हूं: "टैग": [{"नाम": "टैग 1"}]। मैं इसे सूची में सरल करना चाहूंगा, क्या यह संभव है: "टैग": ["टैग 1", "टैग 2", ...]
kengcc

2
का उपयोग करें 'टैग = serializers.SlugRelatedField (कई = सच, read_only = True, slug_field =' शीर्षक ', // टैग की फ़ायरल्ड आप पोस्टर्सरीलाइज़र में allow_null = True) को दिखाना चाहते हैं
एम। धौआदी

जवाबों:


105

आपको एक की आवश्यकता होगी TagSerializer, जिसके class Metaपास है model = Tag। बाद TagSerializerबनाई गई है, संशोधित करने PostSerializerके साथ many=Trueएक के लिए ManyToManyFieldसंबंध:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        model = Post
        fields = ('tag', 'text',)

उत्तर DRF 3 के लिए है


यह काम करता हैं!!! : डी कोई भी विचार कैसे इस धारावाहिक को सिर्फ एक अल्पविराम से अलग सूची में बदल दिया जाए? वर्ग टैगशेयरलाइज़र (सीरियलाइज़र। मोडेल सेरलाइज़र): वर्ग मेटा: मॉडल = टैग फ़ील्ड = ('नाम')
kengcc

1
अभी, मुझे मिलता है: "टैग": [{"नाम": "टैग 1"}] मैं इसे सरल बनाना चाहूंगा: "टैग": ["टैग 1", "टैग 2", ...]
kengcc

टैग = serializers.ListField (स्रोत = 'टैग')। इससे आपको टैग की प्रत्येक वस्तु के सच प्रतिनिधित्व की सूची मिल जाएगी
सचिन गुप्ता

2
यदि आप पोस्ट के माध्यम से टैग को अपडेट करना चाहते हैं तो क्या होगा? (उदाहरण के लिए read_only नहीं) जब मैं read_only निकालता हूं तो मुझे अजीब व्यवहार हो रहा है और टैग क्षेत्र में अपडेट प्राप्त करने का प्रयास करें (मुझे पहले से मौजूद टैग के बारे में एक त्रुटि मिलती है)
getup8

1
इस read_only=Trueभाग को यहाँ समझाया गया है: django-rest-framework.org/api-guide/relations/…
Pavel Vergeev

25

यह मैंने किया है, मान लीजिए कि एक पुस्तक में एक से अधिक लेखक हो सकते हैं और एक लेखक के पास एक से अधिक पुस्तक हो सकती हैं:

class Author(models.Model):
    name = models.CharField(max_length=100, default="")
    last_name = models.IntegerField(default=0)

class Book(models.Model):
    authors = models.ManyToManyField(Author, related_name="book_list", blank=True)
    name = models.CharField(max_length=100, default="")
    published = models.BooleanField(default=True)

सीरियल पर:

class BookSerializer(serializers.ModelSerializer):
    authors = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all(), many=True)

    class Meta:
        model = Book
        fields = ('id', 'name', 'published', 'authors')


class AuthorSerializer(serializers.ModelSerializer):
    book_list = BookSerializer(many=True, read_only=True)

    class Meta:
        model = Author
        fields = ('id', 'name', 'last_name', 'book_list')

कोई विचार है कि हम पुस्तक इकाई बनाने पर लेखक कैसे बना सकते हैं ??
किशन मेहता

2
हां, यह दृश्य वर्ग पर किया जाना है, कृपया एक और प्रश्न पोस्ट करें यदि आप अधिक विस्तृत उत्तर चाहते हैं
यीशु अल्मारल - हैकप्रेंडे

8

इस तरह से @ ब्रायन के उत्तर "टैग": [{"नाम": "टैग 1"}] को "टैग": ["टैग 1", "टैग 2", ...] से जोड़ा जा सकता है:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        ...

class TagSerializer(serializers.RelatedField):

     def to_representation(self, value):
         return value.name

     class Meta:
        model = Tag

अधिक जानकारी यहाँ: https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields



4

Django 2.0

कई क्षेत्रों के लिए, यदि आप विशिष्ट एक चाहते हैं:

class QuestionSerializer(serializers.ModelSerializer):

    topics_list = serializers.SerializerMethodField()

    def get_topics_list(self, instance):
        names = []
        a = instance.topics.get_queryset()
        for i in a:
            names.append(i.desc)
        return names
    class Meta:
        model = Question
        fields = ('topics_list',)

get_topics_listआप के लिए सरल कर सकते हैंreturn list(instance.topics.values_list('desc', flat=True))
bdoubleu

2

Init पद्धति पर क्रमिक रूप से आप क्वेरी को फ़ील्ड में पास कर सकते हैं और rest_framework आईडी को उस क्वेरी पर मान्य कर सकता है

1) सबसे पहले अपने serializer को serializers.ModelSerializer से विस्तारित करें

class YourSerializer(serializers.ModelSerializer):

2) मेटा क्लास पर फ़ील्ड शामिल करें

class YourSerializer(serializers.ModelSerializer):
  class Meta:
        fields = (..., 'your_field',)

3) इनिट विधि:

def __init__(self, *args, **kwargs):
    super(YourSerializer, self).__init__(*args, **kwargs)
    self.fields['your_field].queryset = <the queryset of your field>

आप फ़िल्टर का उपयोग करके किसी भी तर्क के तहत उस फ़ील्ड के लिए क्वेरीसेट को सीमित कर सकते हैं या सामान्य रूप से आप कर सकते हैं। इस मामले में कि आप सभी का उपयोग करना चाहते हैं .objects.all ()


1

डिफ़ॉल्ट ModelSerializerरिश्तों के लिए प्राथमिक कुंजी का उपयोग करता है। हालाँकि, आप Meta depthविशेषता का उपयोग करके आसानी से नेस्टेड अभ्यावेदन उत्पन्न कर सकते हैं :

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag")
        depth = 1 

जैसा कि प्रलेखन में उल्लेख किया गया है :

depthविकल्प मान एक पूर्णांक है कि रिश्तों कि एक फ्लैट प्रतिनिधित्व करने के लिए वापस जाने से पहले चल जाना चाहिए की गहराई को इंगित करता है करने के लिए सेट किया जाना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.