Curl 如何在Django rest框架上请求.method==PUT、POST

Curl 如何在Django rest框架上请求.method==PUT、POST,curl,django-models,request,django-rest-framework,updatemodel,Curl,Django Models,Request,Django Rest Framework,Updatemodel,我正在使用Django REST框架序列化一些模型 这是我的匹配序列化程序模型 class MatchSerializer(serializers.ModelSerializer): field = serializers.SlugRelatedField(queryset=Field.objects.all(),slug_field='name') class Meta: model = Match fields = ('url', 'id'

我正在使用Django REST框架序列化一些模型

这是我的匹配序列化程序模型

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',)
在匹配模型中,字段如下所示:

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,)
主队、客队属性是我的团队模型的ForeingKey,不为空

字段属性也是一个ForeignKey,不为null

status_challenge是字符域且不为空

主队球员接受、客队球员接受、主队球员取消、客队球员取消和fichaje球员比赛字段与我的自定义用户模型有很多关系。这些在我的匹配模型中以这种方式定义,如下所示:

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应用程序客户端更新一个匹配对象时,我遇到以下情况:

我有这样的记录:

{
    "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 tool命令将操作放入此记录时,仅在status_challenge字段中执行更新,将其值从Aceptado更改为Pendiente此更新放置完成,我的主队球员接受,客队球员接受,主队球员取消,客队球员取消,和fichaje_players_match数组字段设置为空白或空,其值为remove:

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] % 
目前我的比赛记录是这样的:

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

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

当request.method=='PUT'在我的viewset中以这种方式时,我尝试使用case:

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)
结果是一样的,我现在还不知道如何应对这种情况,对我来说还不够清楚

如何更新模型序列化程序匹配的status_Challenger字段,而不使上面引用的players字段保持空白或删除其内容

更新

及物性的方式如下:

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,)
这是我的自定义用户模型

用户序列化程序:

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',)
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',)
团队模型具有多个字段到用户模型:

这是我的团队序列化程序

在比赛模型中,有主队球员接受、客队球员接受、主队球员取消、客队球员取消和fichaje球员比赛字段,所有这些字段都与用户模型设置存在多个关系。验证用户模型

这是我的匹配序列化程序:

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

不方便的是,我最初在上面描述过。当我申请更新比赛终点记录时,在现场状态中,主队球员接受、客场球员接受、主队球员取消、客场球员取消和菲沙杰球员比赛字段中的记录将被删除或设置为空白,您需要部分更新。PUT调用更新和修补程序调用部分更新。 唯一的区别是partial=True PATCH或partial=False PUT。在视图中初始化序列化程序时,您可以自己设置partial

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

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

你能添加你正在使用的序列化程序吗?你粘贴的那个不会在客场球队球员接受/客场球队球员接受/…@Linovia中返回名字,我知道你告诉我了,但我使用的序列化程序是我问题开头所示的MatchSerializer类。我的MatchSerializer应该返回此属性吗?可能是我在做一些疯狂或无意义的事情。。。我将感谢您的支持。关于客场球队球员的部分[mike,giraldoesteban]来自哪里?@Linovia我的问题已经更新了一次,详细说明了我在这种情况下涉及的模型和序列化程序。我希望我已经理解了你的问题,并对这一冗长的更新表示歉意: