0

私はDjango RESTフレームワークでいくつかのモデルをシリアライズしています。request.method == Django rest frameworkのPUT、POST

これは私のMatchシリアライザモデルMatchモデルで

class MatchSerializer(serializers.ModelSerializer): 

    field = serializers.SlugRelatedField(queryset=Field.objects.all(),slug_field='name') 

    class Meta: 
     model = Match 
     fields = ('url', 'id', 'home_team', 'away_team', 'field', 'match_date', 'check_match_away_team', 'status_challenge', 'home_team_players_accept', 'away_team_players_accept', 'home_team_players_cancel', 'away_team_players_cancel', 'fichaje_players_match',) 

で、フィールドは、次のとおりである:

  • home_teamaway_team属性、私のTeamモデルにForeingKey年代ですヌルではない

  • field属性もForeignKeyで、nullではありません。

  • status_challengeCharFieldとNOT NULL

  • home_team_players_acceptaway_team_players_accepthome_team_players_cancelaway_team_players_cancel、およびfichaje_players_matchフィールドは私のカスタムUserモデルにManyToMany関係を持っています。 :私はカールを介してMatchオブジェクトを更新していますし、私のモバイルiOSアプリのクライアントを介して、私は次のような場合があるとき私の状況がある

    class Match(models.Model): 
    
        home_team_players_accept = models.ManyToManyField(
         settings.AUTH_USER_MODEL, 
         related_name='home_team_players_accept', 
         blank=True,) 
    
        away_team_players_accept = models.ManyToManyField(
         settings.AUTH_USER_MODEL, 
         related_name='away_team_players_accept', 
         blank=True,) 
    
        home_team_players_cancel = models.ManyToManyField(
         settings.AUTH_USER_MODEL, 
         related_name='home_team_players_cancel', 
         blank=True,) 
    
        away_team_players_cancel = models.ManyToManyField(
         settings.AUTH_USER_MODEL, 
         related_name='away_team_players_cancel', 
         blank=True,) 
    
        fichaje_players_match = models.ManyToManyField(
         settings.AUTH_USER_MODEL, 
         related_name='fichaje_players_match', 
         blank=True,) 
    

:これらは、次のように私のMatchモデルでは、この方法の定義されていました

私はこの方法の記録マッチを持っている:

私はこのレコードに curlツールコマンドを経由して操作を入れている
{ 
    "url": "https://myserver/api/matchs/29/", 
    "id": 29, 
    "home_team": "Manchester United", 
    "away_team": "Sempiternos FC", 
    "field": "Joga Bonito", 
    "match_date": "2017-01-02T09:00:05Z", 
    "check_match_away_team": true, 
    "status_challenge": "Aceptado", 
    "home_team_players_accept": [ 
     "paoc", 
     "nuevo" 
    ], 
    "away_team_players_accept": [ 
     "mike", 
     "giraldoesteban" 
    ], 
    "home_team_players_cancel": [ 
     "erick" 
    ], 
    "away_team_players_cancel": [ 
     "Bluse" 
    ], 
    "fichaje_players_match": [ 
     "Oliver" 
    ] 
} 

、ちょうどで私の更新を行います現在

[email protected] : ~ 
[0] % curl -X PUT https://myserver/api/matchs/29/ -d "home_team=Manchester United&away_team=Sempiternos FC&field=Joga Bonito&match_date=2017-01-2T09:00:05Z&check_match_away_team=true&status_challenge=Pendiente" 
{"url":"https://myserver/api/matchs/29/","id":29,"home_team":"Manchester United","away_team":"Sempiternos FC","field":"Joga Bonito","match_date":"2017-01-02T09:00:05Z","check_match_away_team":true,"status_challenge":"Pendiente","home_team_players_accept":[],"away_team_players_accept":[],"home_team_players_cancel":[],"away_team_players_cancel":[],"fichaje_players_match":[]}%   
[email protected] : ~ 
[0] % 

私を:フィールドは、この更新PUTが、私のhome_team_players_acceptで行わaway_team_players_accepthome_team_players_cancelaway_team_players_cancel、およびfichaje_players_match配列フィールドを空白または空に設定され、その値が削除されているAceptadoからPendienteにその値を変更しますマッチレコードは、この方法は次のとおりです。私はAPIを消費する私のモバイルアプリケーションを介してアップデートを実行するときに

enter image description here

これも発生

私は、ビューセットでこの方法のrequest.method == 'PUT'場合と仕事をしてみてください:

class MatchViewSet(viewsets.ModelViewSet): 

    queryset = Match.objects.all() 
    serializer_class = MatchSerializer 
    filter_fields = ('home_team','away_team', 'status_challenge', 'fichaje_players_match',) 

    @api_view(['PUT']) 
    def match_detail(request, pk): 
     if request.method == 'PUT': 
      serializer = MatchSerializer() 
      if serializer.is_valid(): 
       serializer.save() 
       return Response(serializer) 
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

そして結果はこのような状況に対処するための方法を、この瞬間に、私は不明で、同じであるとthe guideがために十分明確ではありませんme

モデルシリアライザMatchstatus_challengeフィールドを更新する方法上記参照先のプレーヤフィールドが空白になっていないか、コンテンツを削除しないで更新する方法


UPDATE

推移は、次のようにいくつかの方法は次のとおりです。Userモデル私の習慣がある

class User(AbstractBaseUser, PermissionsMixin): 
    ... other attributes ... 

    team = models.ForeignKey(
     'games_information.Team', 
     null=True, 
     blank=True, 
     verbose_name='Equipo en el que juega',  
    ) 

Userシリアライザ:

class UserSerializer(serializers.ModelSerializer): 
    username = serializers.CharField(validators=[UniqueValidator(queryset=User.objects.all(), message='Lo sentimos, existe un fichaje con este nombre de usuario')]) 
    email = serializers.EmailField(validators=[UniqueValidator(queryset=User.objects.all(), message='Lo sentimos, alguien ya ha sido fichado con este correo electrónico')]) 

    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 

    def update(self, instance, validated_data): 
     for attr, value in validated_data.items(): 
      if attr == 'password': 
       instance.set_password(value) 
      else: 
       setattr(instance, attr, value) 
     instance.save() 
     return instance 

    class Meta: 
     model = User 
     fields = ('url', 'username', 'password', 'first_name','last_name', 
        'age', 'sex', 'photo', 'email', 'is_player', 'team', 
        'position', 'is_staff', 'is_active', 'is_superuser', 
        'is_player', 'weight', 'height', 'nickname', 
        'number_matches', 'accomplished_matches', 
        'time_available', 'leg_profile', 'number_shirt_preferred', 
        'team_support', 'player_preferred', 'last_login',) 

TeamモデルがUserモデルにManyToManyフィールドがあります、これは私のTeamSerializer

class TeamSerializer(serializers.ModelSerializer): 

    name = serializers.CharField(validators=[UniqueValidator(queryset=Team.objects.all(), message='Lo sentimos, ya existe un equipo con este nombre')]) 
    place_origin = serializers.SlugRelatedField(queryset=Field.objects.all(),slug_field='name') 

    class Meta: 
     model = Team 
     fields = ('url', 'name', 'image', 'players', 'modality', 'branch', 'category', 'category_name', 'place_origin', 'game_day',) 

ある

class Team(models.Model): 

    ... other fields ... 

    players = models.ManyToManyField(
     settings.AUTH_USER_MODEL, 
     related_name='players', 
     blank=True, 
    ) 

マッチモデルをhome_team_players_acceptaway_team_players_accepthome_team_players_cancelaway_team_players_cancelfichaje_players_matchフィールドを持っています、すべてManyToManyUserモデル(settings.AUTH_USER_MODEL

class Match(models.Model): 

     ... other fields ... 
     STATUS_CHALLENGE_CHOICES = (
      (ACCEPTED_CHALLENGE, u'Aceptado'), 
      (PENDING_CHALLENGE, u'Pendiente'), 
      (CANCELLED_CHALLENGE, u'Cancelado'), 
      (FICHAJE, u'Fichaje'), 
     ) 
     status_challenge = models.CharField(
      choices=STATUS_CHALLENGE_CHOICES, 
      max_length=40, 
      default=True, 
      blank=False, 
      verbose_name='Estado del desafío' 
     ) 
     home_team_players_accept = models.ManyToManyField(
      settings.AUTH_USER_MODEL, 
      related_name='home_team_players_accept', 
      blank=True,) 

     away_team_players_accept = models.ManyToManyField(
      settings.AUTH_USER_MODEL, 
      related_name='away_team_players_accept', 
      blank=True,) 

     home_team_players_cancel = models.ManyToManyField(
      settings.AUTH_USER_MODEL, 
      related_name='home_team_players_cancel', 
      blank=True,) 

     away_team_players_cancel = models.ManyToManyField(
      settings.AUTH_USER_MODEL, 
      related_name='away_team_players_cancel', 
      blank=True,) 

     fichaje_players_match = models.ManyToManyField(
      settings.AUTH_USER_MODEL, 
      related_name='fichaje_players_match', 
      blank=True,) 

これは私のMatchシリアライザです:

class MatchSerializer(serializers.ModelSerializer): 

     field = serializers.SlugRelatedField(queryset=Field.objects.all(),slug_field='name') 

     class Meta: 
      model = Match 
      fields = ('url', 'id', 'home_team', 'away_team', 'field', 'match_date', 'check_match_away_team', 'status_challenge', 'home_team_players_accept', 'away_team_players_accept', 'home_team_players_cancel', 'away_team_players_cancel', 'fichaje_players_match',) 

不便は私が最初に上記のことです。私は、エンドポイントのレコードに一致するように更新するように適用すると、あなたが部分的に更新する必要がhome_team_players_acceptstatus_challengeレコードのフィールドに、away_team_players_accepthome_team_players_cancelaway_team_players_cancelfichaje_players_matchフィールドが削除されているか、空白

+1

あなたが使用しているシリアライザを追加してもらえますか?あなたが貼り付けたものは、away_team_players_accept/away_team_players_accept/...にある名前を返しません。 – Linovia

+0

@Linovia私があなたに教えてくれたことを理解しましたが、私が使用しているシリアライザは、質問の冒頭に示された 'MatchSerializer'クラスです。私の 'MatchSerializer'はこの属性を返すでしょうか?私はあなたのサポートに感謝します – bgarcial

+0

'' away_team_players_accept ":[" mike "、" giraldoesteban "]のセクションはどこから来ますか? – Linovia

答えて

1

に設定します。 PUTはupdate()を呼び出し、PATCHはpartial_update()を呼び出します。 唯一の違いは、partial = True(PATCH)またはpartial = False(PUT)です。ビュー内でシリアライザを初期化するときに、部分的に自分自身を設定することもできます。あなたはPUTと部分更新を実行するために、DjangoのRESTフレームワークコード(mixins.py)のようにそれを行うことができます

def update(self, request, *args, **kwargs): 
    kwargs['partial'] = True 
    return super(YourCustomView, self).update(request, *args, **kwargs) 
関連する問題