0

Ich arbeite mit Django REST Framework Serialisierung einiger Modelle.How to request.method == PUT, POST auf Django Rest Framework

Das ist mein Match Serializer Modell

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',) 

Im Match Modell sind die Felder wie folgt:

  • home_team, away_team Attribute sind ein ForeingKey ‚s meinem Team Modell und nicht null

  • field Attribut ist ein ForeignKey auch und nicht null.

  • status_challenge ist ein CharField und nicht null

  • home_team_players_accept, away_team_players_accept, home_team_players_cancel, away_team_players_cancel und fichaje_players_match Felder haben eine ManyToMany Beziehung zu meinen benutzerdefinierten User Modell. Diese wurden definiert diese Art und Weise in meinem Match Modell wie folgt:

    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,) 
    

Meine Situation ist, wenn ich aktualisiere bin ein Match-Objekt über curl und durch mein Handy-App für iOS-Client, ich habe den folgenden Fall:

ich habe einen Rekord Spiel dieser Art und Weise:

{ 
    "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" 
    ] 
} 

Als ich die Bedienung über curl Werkzeugbefehl für diesen Eintrag gesetzt haben, führen mein Update nur in der status_challenge Feld ihren Wert Aceptado-Pendiente dieses Update PUT Wechsel erfolgt, mit meinem home_team_players_accept, away_team_players_accept, home_team_players_cancel, away_team_players_cancel und fichaje_players_match Array-Felder werden auf leer oder leer, ihre Werte entfernen sind:

[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] % 

Derzeit meine Spielaufzeichnung ist dieser Weg:

enter image description here

Dies auch dann auftreten, wenn ich das Update über meine mobile Anwendung ausführen, die die API verbrauchen

Ich versuche, die Arbeit mit dem Fall, wenn request.method == 'PUT' dieser Art und Weise in meinem Viewset:

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) 

und das Ergebnis ist das gleiche, die ich in diesem Moment nicht bekannt, wie diese Situation zu begegnen und the guide ist nicht klar genug für me

Wie kann ich das status_challenge Feld des Modells Serializer aktualisieren Match ohne dass die Feldspieler oben in leeren oder entfernen ihre Inhalte waren verwiesen?


UPDATE

Die Transitivität ist von gewisser Weise wie folgt:

Es ist meine Gewohnheit User Modell

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

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

Die User Serializer:

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',) 

Das Team Modell haben ein ManyToMany Feld User Modell:

class Team(models.Model): 

    ... other fields ... 

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

Das ist mein 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',) 

Das Spiel Modell haben die home_team_players_accept, away_team_players_accept, home_team_players_cancel, away_team_players_cancel und fichaje_players_match Felder, alle in ManyToMany Beziehung mit dem User Modell (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,) 

Das ist mein Match Serializer:

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',) 

Die unbequeme ist, dass ich zunächst oben beschrieben. Wenn ich mich bewerben zu aktualisieren Endpunkt Datensatz passt, im Bereich status_challenge die Datensätze in den home_team_players_accept, away_team_players_accept, home_team_players_cancel, away_team_players_cancel und fichaje_players_match Felder entfernt oder auf leere

+1

Könnten Sie den Serializer hinzufügen Sie verwenden? Der Name, den Sie eingefügt haben, würde keine Namen in away_team_players_accept/away_team_players_accept/... zurückgeben. – Linovia

+0

@Linovia Ich verstehe, dass Sie mir sagen, aber der Serializer, den ich verwende, ist die 'MatchSerializer'-Klasse, die am Anfang meiner Frage steht. Mein 'MatchSerializer' sollte diese Attribute zurückgeben? ist möglich, dass ich etwas verrücktes oder nicht sinnvolles mache ... Ich schätze deine Unterstützung – bgarcial

+0

Woher kommt der Abschnitt mit '" away_team_players_accept ": [" mike "," giraldoesteban "],' kommt? – Linovia

Antwort

1

benötigen Sie teilweise Aktualisierung. PUT ruft update() auf und PATCH ruft partial_update() auf. Der einzige Unterschied ist partiell = True (PATCH) oder partially = False (PUT). Und Sie können sich selbst partitionieren, wenn Sie den Serializer in Ihren Ansichten initialisieren.

Sie können es wie in Django REST Framework-Code (mixins.py), teilweise Updates mit PUT ausführen:

def update(self, request, *args, **kwargs): 
    kwargs['partial'] = True 
    return super(YourCustomView, self).update(request, *args, **kwargs) 
Verwandte Themen