Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate a model in django rest framework?

I have a model that is essentially a single table with four lookup tables. One of the lookup tables is to specify a type. Based on the type (of which there are four), the requirements on the fields change. For example if the type is 'Survey' the field number_of_unique_contacts is required, but not for any other type.

I considered using multiple table and an DB pattern based on modeling inheritance. But that doesn't make sense as there are only four types, and only 6 fields are in play as 'contextually required' dependent on the type. That being said, I would be open to multiple Models inside of Django, but I prefer the REST framework to only present a single URI (not one per TYPE).

The question at hand is: what is the best way to validate the model on POST/PUT requests? Am i better off choosing another database schema (as mentioned I think I have what feels right to me)? Should restructure my python model (again a single main class with four lookups)?

I am new to Django and python, so please be gentle (.NET/Java background). And thank you in advance

What I think is relevant code (honestly the code doesn't probably matter, as this is more of a design question, but I always feel weird posting w/o code - at lease for context)

class MySerializer(serializers.ModelSerializer):
    proposal_side = serializers.SlugRelatedField(many=False, read_only=False, slug_field='proposal_side')
    my_proposal_type = serializers.SlugRelatedField(many=False, read_only=False, slug_field='proposal_type')
    my_proposal_delivery_type = serializers.SlugRelatedField(many=False, read_only=False, slug_field='delivery_type')
    my_survey_method = serializers.SlugRelatedField(many=False, read_only=False, slug_field='method')
    class Meta:
        model = diliModels.Proposal
        fields = (
            'id'
            ,'my_proposal_side'
            ,'my_proposal_type'
            ,'number_of_participants'
            ,'cost_per_participants'
            ,'minimum_dollar_commitment'
            ,'commercial_terms'
            ,'is_publicly_visible'
            ,'is_anonymous'
            ,'is_republish'
            ,'name'
            ,'my_delivery_type'
            ,'my_survey_method'
            ,'number_of_unique_contacts'
            ,'availability_start'
            ,'availability_end'
            ,'location_country'
            ,'location_city'
            ,'location_state'
            ,'description'
            ,'desired_meetings'
        )


class MyViewSet(viewsets.ModelViewSet):
    paginate_by = 100

    queryset = myModels\
        .MyProposal\
        .objects\
        .prefetch_related('blah')
    print 'SQL::MyViewSet: ' + str(queryset.query)
    serializer_class = serializers.MySerializer
like image 371
akaphenom Avatar asked Dec 05 '13 18:12

akaphenom


1 Answers

Add a validate method to the serializer class is one option

class MySerializer(serializers.ModelSerializer):
    proposal_side = serializers.SlugRelatedField(many=False, read_only=False, slug_field='proposal_side')
    my_proposal_type = serializers.SlugRelatedField(many=False, read_only=False, slug_field='proposal_type')
    my_proposal_delivery_type = serializers.SlugRelatedField(many=False, read_only=False, slug_field='delivery_type')
    my_survey_method = serializers.SlugRelatedField(many=False, read_only=False, slug_field='method')
    class Meta:
        model = diliModels.Proposal
        fields = (
            'id'
            ,'my_proposal_side'
            ,'my_proposal_type'
            ,'number_of_participants'
            ,'cost_per_participants'
            ,'minimum_dollar_commitment'
            ,'commercial_terms'
            ,'is_publicly_visible'
            ,'is_anonymous'
            ,'is_republish'
            ,'name'
            ,'my_delivery_type'
            ,'my_survey_method'
            ,'number_of_unique_contacts'
            ,'availability_start'
            ,'availability_end'
            ,'location_country'
            ,'location_city'
            ,'location_state'
            ,'description'
            ,'desired_meetings'
        )

    def validate(self, attrs):
         raise serializers.ValidationError("error")
         return attrs
like image 67
akaphenom Avatar answered Oct 15 '22 06:10

akaphenom