জাজানো রিস্ট ফ্রেমওয়ার্ক: মডেলশিরাইজারে অতিরিক্ত ক্ষেত্র যুক্ত করা


147

আমি একটি মডেলকে সিরিয়াল করতে চাই, তবে একটি অতিরিক্ত ক্ষেত্র অন্তর্ভুক্ত করতে চাই যার জন্য মডেল উদাহরণে সিরিয়ালযুক্ত হওয়ার জন্য কিছু ডাটাবেস লুকআপ করা দরকার:

class FooSerializer(serializers.ModelSerializer):
  my_field = ... # result of some database queries on the input Foo object
  class Meta:
        model = Foo
        fields = ('id', 'name', 'myfield')

এটি করার সঠিক উপায় কী? আমি দেখতে পাচ্ছি যে আপনি সিরিয়ালাইজারের কাছে অতিরিক্ত "প্রসঙ্গে" পাস করতে পারেন , কোনও প্রসঙ্গ অভিধানে অতিরিক্ত ক্ষেত্রে পাস করার সঠিক উত্তর? এই পদ্ধতির সাথে, আমার প্রয়োজনীয় ক্ষেত্রটি পাওয়ার যুক্তিটি সিরিয়ালাইজার সংজ্ঞায় স্বয়ংসম্পূর্ণ হবে না, যা প্রতিটি সিরিয়ালাইজড দৃষ্টান্তের প্রয়োজন হিসাবে আদর্শ my_field। ডিআরএফ সিরিয়ালাইজ ডকুমেন্টেশনের অন্য কোথাও এটিতে বলা হয়েছে "অতিরিক্ত ক্ষেত্রগুলি কোনও সম্পত্তির সাথে মিল রাখতে পারে বা মডেলটিতে কল করতে পারে"। আমি অতিরিক্ত কথা বলছি কি? আমি কী Fooএর মডেল সংজ্ঞায় এমন কোনও ক্রিয়াকলাপ সংজ্ঞায়িত করব যা my_fieldমানটি ফেরত দেয় , এবং সিরিয়ালাইজারে আমি আমার_ফিল্ডটিকে সেই কলযোগ্যটিতে রেখে দিয়েছি? দেখতে কেমন লাগে?

অগ্রিম ধন্যবাদ, প্রয়োজনে প্রশ্নটি পরিষ্কার করে খুশি।

উত্তর:


224

আমি মনে করি সিরিয়ালাইজার মেথডফিল্ড যা আপনি খুঁজছেন তা:

class FooSerializer(serializers.ModelSerializer):
  my_field = serializers.SerializerMethodField('is_named_bar')

  def is_named_bar(self, foo):
      return foo.name == "bar" 

  class Meta:
    model = Foo
    fields = ('id', 'name', 'my_field')

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield


19
এই জাতীয় ক্ষেত্রে বৈধতা যুক্ত করা সম্ভব? আমার প্রশ্নটি: কীভাবে কাস্টম পোস্টের মানগুলি গ্রহণ করা যায় যা বৈধ করা যেতে পারে এবং পোস্ট_সেভ () হ্যান্ডলারে প্রক্রিয়া করা যায়?
আল্প

20
দ্রষ্টব্য যে সিরিয়ালাইজার মেথডফিল্ড কেবল পঠনযোগ্য, সুতরাং এটি আগত পোষ্ট / পুট / প্যাচগুলির জন্য কাজ করবে না।
স্কট এ

24
ডিআরএফ 3-তে, এটিকে পরিবর্তন করা হয় field_name = serializers.SerializerMethodField()এবংdef get_field_name(self, obj):
রাসায়নিক প্রোগ্রামার

1
কি fooযখন Def একটি SerializerMethodField? ক্রিয়েটিএপিভিউ ব্যবহার করার সময়, foo কি সংরক্ষণ করা থাকে তবে is_নেম_বার () পদ্ধতিটি ব্যবহার করতে পারবেন?
244boy

সুতরাং, এই উত্তরের উপর ভিত্তি করে, আপনি যদি নিজের সিরিয়ালের সাথে 12 টি অতিরিক্ত ক্ষেত্র বলতে চান, তবে আপনাকে প্রতিটি ক্ষেত্রের জন্য 12 নির্দিষ্ট পদ্ধতি নির্ধারণ করতে হবে যা কেবল foo.field_custom ফেরত দেয়?
AlxVallejo

41

আপনি আপনার মডেল পদ্ধতিটি সম্পত্তিতে পরিবর্তন করতে পারেন এবং এই পদ্ধতির সাহায্যে এটি সিরিয়ালাইজারে ব্যবহার করতে পারেন।

class Foo(models.Model):
    . . .
    @property
    def my_field(self):
        return stuff
    . . .

class FooSerializer(ModelSerializer):
    my_field = serializers.ReadOnlyField(source='my_field')

    class Meta:
        model = Foo
        fields = ('my_field',)

সম্পাদনা করুন: বিশ্রাম কাঠামোর সাম্প্রতিক সংস্করণগুলির সাথে (আমি 3.3.3 চেষ্টা করেছি), আপনাকে সম্পত্তিতে পরিবর্তন করার দরকার নেই। মডেল পদ্ধতি ঠিক কাজ করবে।


ধন্যবাদ @ ওয়াসিল! আমি জ্যাঙ্গো মডেলগুলিতে সম্পত্তি ব্যবহারের সাথে পরিচিত নই এবং এর অর্থ কী তা সম্পর্কে ভাল ব্যাখ্যা খুঁজে পাচ্ছি না। তুমি কি ব্যাখ্যা করতে পারো? এখানে @ প্রপার্টি ডেকরেটারের মূল বক্তব্য কী?
নীল

2
এর অর্থ আপনি এই পদ্ধতির কোনও সম্পত্তির মতো কল করতে পারেন: অর্থাত্ শোভাকর ব্যতীত variable = model_instance.my_fieldএকই ফলাফল দেয় variable = model_instance.my_field()। এছাড়াও: stackoverflow.com/a/6618176/2198571
Wasil Sergejczyk

1
এটি কাজ করছে না, কমপক্ষে জ্যাঙ্গো 1.5.1.1 / djangorestframework == 2.3.10 এ। "ক্ষেত্রগুলি" মেটা অ্যাট্রিবিউটকে স্পষ্টভাবে উল্লেখ করা হলেও মডেলশিরাইজার যথাযথতা পাচ্ছে না।
ygneo

9
আপনার সিরিয়ালাইজারে ক্ষেত্রটি যুক্ত করতে হবে কারণ এটি কোনও আসল মডেলফিল্ড নয়: মাই_ফিল্ড = সিরিয়ালাইজার F ফিল্ড (উত্স = 'আমার_ফিল্ড')
মারিয়াস

2
source='my_field' আর প্রয়োজন নেই এবং একটি ব্যতিক্রম বাড়াতে হবে
গিলাইম ভিনসেন্ট

13

জ্যাঙ্গো রেস্ট ফ্রেমওয়ার্কের শেষ সংস্করণ সহ, আপনি যে মডেলটি যুক্ত করতে চান তার নাম সহ আপনার মডেলটিতে একটি পদ্ধতি তৈরি করা দরকার। ত্রুটি বাড়াতে হবে না @propertyএবং প্রয়োজন নেই source='field'

class Foo(models.Model):
    . . .
    def foo(self):
        return 'stuff'
    . . .

class FooSerializer(ModelSerializer):
    foo = serializers.ReadOnlyField()

    class Meta:
        model = Foo
        fields = ('foo',)

আমি যদি requestডিফ foo (স্ব) এর ভিতরে অবজেক্ট রাখতে চাই যা ফু এর মান পরিবর্তন করতে পারে? (উদাহরণস্বরূপ একটি
অনুরোধ.ইউজার

1
যদি ফু এর মান অনুরোধ থেকে আসে?
saran3h

11

অনুরূপ প্রশ্নের আমার প্রতিক্রিয়া ( এখানে ) দরকারী হতে পারে।

আপনার যদি নিম্নলিখিত পদ্ধতিতে কোনও মডেল পদ্ধতি সংজ্ঞায়িত করা থাকে:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

আপনি নিজের সিরিয়ালাইজারে বলার পদ্ধতিটি কল করার ফলাফলটি এমনভাবে যুক্ত করতে পারেন:

class MyModelSerializer(serializers.ModelSerializer):
    model_method_field = serializers.CharField(source='model_method')

PS যেহেতু কাস্টম ক্ষেত্রটি আপনার মডেলের কোনও ক্ষেত্র নয়, আপনি সাধারণত এটিকে কেবল পঠনযোগ্য করে তুলতে চাই:

class Meta:
    model = MyModel
    read_only_fields = (
        'model_method_field',
        )

10

আপনি যদি নিজের অতিরিক্ত ক্ষেত্রে পড়তে এবং লিখতে চান তবে আপনি একটি নতুন কাস্টম সিরিয়ালাইজার ব্যবহার করতে পারেন যা সিরিয়ালাইজারকে প্রসারিত করে erial

class ExtraFieldSerializer(serializers.Serializer):
    def to_representation(self, instance): 
        # this would have the same as body as in a SerializerMethodField
        return 'my logic here'

    def to_internal_value(self, data):
        # This must return a dictionary that will be used to
        # update the caller's validation data, i.e. if the result
        # produced should just be set back into the field that this
        # serializer is set to, return the following:
        return {
          self.field_name: 'Any python object made with data: %s' % data
        }

class MyModelSerializer(serializers.ModelSerializer):
    my_extra_field = ExtraFieldSerializer(source='*')

    class Meta:
        model = MyModel
        fields = ['id', 'my_extra_field']

আমি কিছু কাস্টম যুক্তি দিয়ে সম্পর্কিত নেস্টেড ক্ষেত্রে এটি ব্যবহার করি


2

এটি আমার পক্ষে কাজ করেছে .যদি আমরা কেবল মডেলশিরাইজারে একটি অতিরিক্ত ক্ষেত্র যুক্ত করতে চাই, আমরা নীচের মতো এটি করতে পারি এবং কিছু গণনা দেখার পরে ক্ষেত্রটি কিছুটা ভাল বরাদ্দ করা যেতে পারে। বা কিছু ক্ষেত্রে যদি আমরা API প্রতিক্রিয়াতে প্যারামিটারগুলি প্রেরণ করতে চাই।

মডেল.পি

class Foo(models.Model):
    """Model Foo"""
    name = models.CharField(max_length=30, help_text="Customer Name")



   **

সিরিয়ালাইজারে.পি

**

class FooSerializer(serializers.ModelSerializer):
    retrieved_time = serializers.SerializerMethodField()

    @classmethod
    def get_retrieved_time(self, object):
        """getter method to add field retrieved_time"""
        return None

  class Meta:
        model = Foo
        fields = ('id', 'name', 'retrieved_time ')

**

আশা করি এটি কারও সাহায্য করতে পারে

**


0

যেমন রাসায়নিক প্রগ্রামার এই মন্তব্যে বলেছিলেন , সর্বশেষ ডিআরএফ-এ আপনি কেবল এটির মতো করতে পারেন:

class FooSerializer(serializers.ModelSerializer):
    extra_field = serializers.SerializerMethodField()

    def get_extra_field(self, foo_instance):
        return foo_instance.a + foo_instance.b

    class Meta:
        model = Foo
        fields = ('extra_field', ...)

ডিআরএফ ডক্স উত্স

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.