如何request.method == PUT,在Django休息框架上发布

时间:2017-01-26 04:15:48

标签: curl django-models request django-rest-framework updatemodel

我正在使用Django REST Framework序列化某些模型。

这是我的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',)

Match模型中,字段如下:

  • home_teamaway_team属性是我ForeingKey模型的Team而非空

  • field属性也是ForeignKey而非空。

  • status_challengeCharField而非空

  • home_team_players_acceptaway_team_players_accepthome_team_players_cancelaway_team_players_cancelfichaje_players_match字段与我的自定义{ManyToManyUser个关系1}}模型。这些是在Match模型中以这种方式定义的,例如:

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

我的情况是,当我通过curl和我的移动iOS应用客户端更新一个Match对象时,我有以下情况:

我有这样的记录匹配:

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

当我通过curl工具命令对此记录进行PUT操作时,请在status_challenge字段中执行我的更新,将其值从Aceptado更改为Pendiente此更新PUT已完成,我的home_team_players_acceptaway_team_players_accepthome_team_players_cancelaway_team_players_cancelfichaje_players_match数组字段设置为空或空,其值将被删除:< / p>

bgarcial@elpug : ~
[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":[]}%           
bgarcial@elpug : ~
[0] % 

目前我的比赛记录是这样的:

enter image description here

当我通过使用API​​的移动应用程序执行更新时,也会发生这种情况

我尝试在我的视图中以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对我来说还不够明确

如何更新模型序列化程序status_challenge的{​​{1}}字段,而不是上面提到的玩家字段留空或删除其内容?

更新

传递性在某种程度上如下:

我的自定义Match型号

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字段到ManyToMany模型:

User

这是我的class Team(models.Model): ... other fields ... players = models.ManyToManyField( settings.AUTH_USER_MODEL, related_name='players', blank=True, )

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',) home_team_players_acceptaway_team_players_accepthome_team_players_cancelaway_team_players_cancel字段,所有字段均与fichaje_players_match关系ManyToMany模型(User

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',) 字段中status_challengehome_team_players_acceptaway_team_players_accepthome_team_players_cancel和{{1} }字段被删除或设置为空白

1 个答案:

答案 0 :(得分:1)

您需要部分更新。 PUT调用update()和PATCH调用partial_update()。 唯一的区别是partial = True(PATCH)或partial = False(PUT)。您可以在视图中初始化序列化程序时自行设置部分。

您可以像在Django REST框架代码(mixins.py)中那样使用PUT执行部分更新:

CreateFileA()