2017-07-14 80 views
1

私はシリアライザを使用してジャンゴ残りのフレームワーク上でAPIを作るとき、保存()、()を作成し、更新()メソッドの間の正確な異なる教えてください、私のコードサンプルは、続くdjango restフレームワークでsave()、create()、update()の違いは何ですか?

View.pyようです混乱しmは

クラスは、AddUser(views.APIView):

serializer_class = UserForAdminSerializer 

def post(self, request, *args, **kwargs): 

    serializer = UserForAdminSerializer(data=request.data) 

    if serializer.is_valid(): 

     serializer.save() 
     return Response(serializer.data, status=status.HTTP_201_CREATED) 
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

serializers.py

クラスU serForAdminSerializer(serializers.ModelSerializer):保存に使用view.pyファイルイムで上記のコードで

first_name = serializers.CharField(max_length=30) 
last_name = serializers.CharField(max_length=30) 
name = serializers.CharField(max_length=30) 
password = serializers.CharField(max_length=20, style={'input_type': 'password'}) 

class Meta: 
    model = User 
    fields = ('id', 'url', 'first_name', 'last_name', 'name', 'username', 'email', 'password', 
       'total_exp_year', 'total_exp_month', 'voteup_count', 'is_featured', 
       'is_active', 'headline', 'description', 'profile_picture',) 

def create(self, validated_data): 
    password = validated_data.pop('password', None) 
    instance = self.Meta.model(**validated_data) 
    if password is not None: 
     instance.set_password(password) 
    instance.save() 
    return instance 

()メソッドとserializers.py保存使用して()またはupdate()メソッドは、それが働いているか私に説明してください。

答えて

1

通常のコードをよく理解してもらうための最善の方法は、実際にそれを読んで、それではsourceを見てみましょうすることです:

class BaseSerializer(Field): 
    ... 
    def update(self, instance, validated_data): 
     raise NotImplementedError('`update()` must be implemented.') 

    def create(self, validated_data): 
     raise NotImplementedError('`create()` must be implemented.') 

    def save(self, **kwargs): 
     ... 
     ... a lot of assertions and safety checks ... 
     ... 

     validated_data = dict(
      list(self.validated_data.items()) + 
      list(kwargs.items()) 
     ) 

     if self.instance is not None: 
      self.instance = self.update(self.instance, validated_data) 
      .... 
     else: 
      self.instance = self.create(validated_data) 
      ... 
     return self.instance 

わかりましたので、この基本クラスのメソッドupdatecreateは実装される具体的なサブクラスに残されます(詳細はListSerializerまたはModelSerializerなどのシリアライザによって異なります)。

しかしながら、saveが実装されたオブジェクトが(if self.instance is not None)新規または既存であり、それぞれupdate又はcreateを呼び出す場合には、基本的にチェックします。 このコードは、他のすべてのシリアライザで呼び出されます。

のは、具体的なサブクラスを見てみましょう:

def create(self, validated_data): 
    ... 
    ... some stuff happening 
    ... 

    try: 
     # Here is the important part! Creating new object! 
     instance = ModelClass.objects.create(**validated_data) 
    except TypeError: 
     raise TypeError(msg) 

    # Save many-to-many relationships after the instance is created. 
    if many_to_many: 
     for field_name, value in many_to_many.items(): 
      set_many(instance, field_name, value) 

    return instance 


def update(self, instance, validated_data): 
    raise_errors_on_nested_writes('update', self, validated_data) 
    info = model_meta.get_field_info(instance) 

    # Simply set each attribute on the instance, and then save it. 
    # Note that unlike `.create()` we don't need to treat many-to-many 
    # relationships as being a special case. During updates we already 
    # have an instance pk for the relationships to be associated with. 
    for attr, value in validated_data.items(): 
     if attr in info.relations and info.relations[attr].to_many: 
      set_many(instance, attr, value) 
     else: 
      setattr(instance, attr, value) 
    instance.save() 

    return instance 

あなたがオブジェクトの属性の値を設定するには、両方のcreateupdateコールset_many(instance, attr, value)を見ることができるように。ただし、createとなります。ModelClass.objects.create(**validated_data)です。これは実際に新しいインスタンスを作成します。

これが少しクリアすることを願っています。

+0

ありがとうSiegmeyer :) –

1

Django Rest Framework documentationでは、いつsaveメソッドをオーバーライドするのか、そしていつ作成メソッドをオーバーライドするのかが明確に説明されています。

私は意味がないかもしれないいくつかのケースでは


あなたの便宜のためにここに.create()と.update()メソッド名をその説明を掲示しています。たとえば、連絡先フォームでは、新しいインスタンスを作成するのではなく、電子メールやその他のメッセージを送信する場合があります。 これらの場合、代わりに.save()を直接読みやすく、読みやすく、意味のあるものとして上書きすることもできます。
例: -

class ContactForm(serializers.Serializer): 
    email = serializers.EmailField() 
    message = serializers.CharField() 

    def save(self): 
     email = self.validated_data['email'] 
     message = self.validated_data['message'] 
     send_email(from=email, message=message) 
+0

ありがとうArpit SVT :) –

+0

答えが正しいとマークしてくれました。 –

+0

正しいとマークするにはどうすればよいですか? –

関連する問題