Praful Bagai
Praful Bagai

Reputation: 17392

DRF - Filter queryset in PrimaryKeyRelatedField

I've the following models:

class ModelX(models.Model):

    STATUS_CHOICES = (
        (0, 'ABC'),
        (1, 'DEF'),
    )
    status = models.IntegerField(choices=STATUS_CHOICES)
    user = models.ForeignKey(Users)


class Users(models.Model):
    phone_number = models.Charfield()

and the serializer for ModelX is :

class ModelXSerializer(serializers.ModelSerializer):
    phone_number = serializers.PrimaryKeyRelatedField(
        source='user', queryset=Users.objects.get(phone_number=phone_number))

    class Meta:
        model = ModelX
        fields = ('phone_number',)

In the request for creating the ModelX record, I get phone_number instead of the user_id. Now, I've to fire a filter query in order get the user instance. How do I do that, ie Users.objects.get(phone_number=phone_number)

Also, when creating a record, the status field will always be 0. The client wont post the status parameter in the body. Its the internal logic. Is there a way in serializers that can set the status field to 0 automatically. Please dont recommend to set this field as default=0 in models. There's some logic behind this. This is just a shorter version of the problem statement.

Upvotes: 3

Views: 2465

Answers (2)

user8060120
user8060120

Reputation:

you can try such version of your serializer, with custom create method:

class ModelXSerializer(serializers.ModelSerializer):
    phone_number = serializers.CharField(source='user.phone_number')

    class Meta:
        model = ModelX
        fields = ('phone_number',)

    def create(self, validated_data):
        phone_number = validated_data['phone_number']
        user = Users.objects.get(phone_number=phone_number)
        instance = ModelX.objects.create(status=0, user=user)
        return instance

details about the source argument.

Upvotes: 2

Huu-Danh Pham
Huu-Danh Pham

Reputation: 291

You can add it in validate function:

class ModelXSerializer(serializers.ModelSerializer):

    def validate(self, attrs):
        attrs = super(ModelXSerializer, self).validate(attrs)
        attrs['status'] = 0
        return attrs

Upvotes: 1

Related Questions