0

Hope someone can help me out here, I am trying to test a post method on an API, but the post method is not working as expected.

When I pass the payload to the post method, the points and de code fields are loaded but the shopper and card fields, which are both Foreing Keys, are not loaded and a null value is passed, as they are required fields I ended up getting an error.

I did check, and the values for self.shopper.pk and self.card.pk are correct.

MYCARDS_URL = reverse('mycards:mycards-list')

def test_create_mycards(self):
    """Test creating a mycards"""
    payload = {
        'shopper': self.shopper.pk,
        'card': self.card.pk,
        'points': 0,
        'code': "code",
    }

    res = APIClient().post(MYCARDS_URL, payload)

I did check to see if was something related to my serializer, but it is all good as you can see:

class MycardsSerializer(serializers.ModelSerializer): """Serializer for cards."""

class Meta:
    model = MyCards
    fields = ['id', 'shopper', 'card', 'updated', 'created']
    read_only_fields = ['id', 'created']

class MycardsDetailSerializer(MycardsSerializer): """Serializer for card detail view."""

class Meta(MycardsSerializer.Meta):
    fields = MycardsSerializer.Meta.fields + [
        'points', 'code']

Here is also my viewset which seems to be ok:

class MycardsViewSet(viewsets.ModelViewSet):
    """View for manage card APIs."""

    serializer_class = serializers.MycardsDetailSerializer
    queryset = MyCards.objects.all()
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        """Retrieve cards for authenticated user."""
        shoppers = list(Shopper.objects.all().filter(
            user=self.request.user).values_list('id'))

        return self.queryset.filter(shopper=shoppers[0]).order_by('-id')

    def get_serializer_class(self):
        """Return the serrializer class for request."""
        if self.action == 'list':
            return serializers.MycardsSerializer

        return self.serializer_class

    def perform_create(self, serializer):
        """Create a new recipe."""
        serializer.save()

I have printed the serializer.dict from inside the perform_create method and got the following: {'_args': (), '_kwargs': {'data': <QueryDict: {'shopper': ['5'], 'card': ['15'], 'points': ['0'], 'code': ['code']}>, 'context': {'request': <rest_framework.request.Request: POST '/api/mycards/'>, 'format': None, 'view': <mycards.views.MycardsViewSet object at 0x7f7ebd4ce400>}}, 'instance': None, 'initial_data': <QueryDict: {'shopper': ['5'], 'card': ['15'], 'points': ['0'], 'code': ['code']}>, 'partial': False, '_context': {'request': <rest_framework.request.Request: POST '/api/mycards/'>, 'format': None, 'view': <mycards.views.MycardsViewSet object at 0x7f7ebd4ce400>}, '_creation_counter': 198, 'read_only': False, 'write_only': False, 'required': True, 'default': <class 'rest_framework.fields.empty'>, 'source': None, 'initial': None, 'label': None, 'help_text': None, 'style': {}, 'allow_null': False, 'field_name': None, 'parent': None, 'error_messages': {'required': 'This field is required.', 'null': 'This field may not be null.', 'invalid': 'Invalid data. Expected a dictionary, but got {datatype}.'}, 'url_field_name': 'url', 'fields': {'id': IntegerField(label='ID', read_only=True), 'shopper': PrimaryKeyRelatedField(read_only=True), 'card': PrimaryKeyRelatedField(read_only=True), 'updated': DateTimeField(read_only=True), 'created': DateTimeField(read_only=True), 'points': IntegerField(max_value=2147483647, min_value=-2147483648, required=False), 'code': CharField(allow_blank=True, allow_null=True, max_length=6, required=False)}, '_validators': [], '_validated_data': OrderedDict([('points', 0), ('code', 'code')]), '_errors': {}}

here I could notice 2 things, first that the values are passed to the serializer as noted on the line below: 'shopper': ['5'], 'card': ['15'], 'points': ['0'], 'code': ['code']

but at the end of the serializer.dict I could find the following message: '_validated_data': OrderedDict([('points', 0), ('code', 'code')]), '_errors':

points and code are going through, but the shopper and the card are not, I just have no idea why is it happening :/

0 Answers0