Eugene K
Eugene K

Reputation: 13

Django Rest Framework: Saving ForeignKey inside OneToOne model

I have 2 models that are OneToOne related and model that is FK to 2nd model

models.py

class Legal(TimeStampedModel):
     name = models.CharField('Name', max_length=255, blank=True)

class LegalCard(TimeStampedModel):
    legal = models.OneToOneField('Legal', related_name='legal_card', on_delete=models.CASCADE)
    branch = models.ForeignKey('Branch', related_name='branch', null=True)
    post_address = models.CharField('Post address', max_length=255, blank=True)

class Branch(TimeStampedModel):
    name = models.CharField('Name',max_length=511)
    code = models.CharField('Code', max_length=6)

Using DRF I made them to behave as single model so I can create or update both:

serializer.py

class LegalSerializer(serializers.ModelSerializer):

    branch = serializers.IntegerField(source='legal_card.branch', allow_null=True, required=False)
    post_address = serializers.CharField(source='legal_card.post_address', allow_blank=True, required=False)

    class Meta:
        model = Legal
        fields = ('id',
                  'name',
                  'branch',
                  'post_address',
                  )
        depth = 2


    def create(self, validated_data):
        legal_card_data = validated_data.pop('legal_card', None)
        legal = super(LegalSerializer, self).create(validated_data)
        self.update_or_create_legal_card(legal, legal_card_data)
        return legal

    def update(self, instance, validated_data):
        legal_card_data = validated_data.pop('legal_card', None)
        self.update_or_create_legal_card(instance, legal_card_data)
        return super(LegalSerializer, self).update(instance, validated_data)

    def update_or_create_legal_card(self, legal, legal_card_data):
        LegalCard.objects.update_or_create(legal=legal, defaults=legal_card_data)

views.py

 class LegalDetailView(generics.RetrieveUpdateDestroyAPIView):
        queryset = Legal.objects.all()
        serializer_class = LegalSerializer

I'm trying to save this by sending FK as integer (I just want to post id of the branch), but I receive error

ValueError: Cannot assign "2": "LegalCard.branch" must be a "Branch" instance.

Is there any way to pass over only ID of the branch?

Thank you

Upvotes: 0

Views: 81

Answers (2)

E. Mozz
E. Mozz

Reputation: 93

Just use legal_card.branch_id instead of legal_card.branch to get just an id, not a related object. And depth = 1

Upvotes: 0

Can Arsoy
Can Arsoy

Reputation: 116

In Django, if you only need the FK value, you can use the FK value that is already on the object you've got rather than getting the related object. Assume you have a Legal and Branch object with id's as 1. Then you can save a LegalCard object by:

LegalCard(legal_id=1,branch_id=1,post_address="Istanbul Street No:1")

Upvotes: 1

Related Questions