Changmin Choi
Changmin Choi

Reputation: 153

Django: How to save data in two models(tables) from one POST request?

I want to save data in two models from a single POST request. Two models (ModelA, ModelB) have the same structures.

The request passes through RESTful API using Django-Rest-Framework.

I tried putting update_or_create() into def perform_create() like below, but it failed. Because, it required that each input data should be Model instance. I don't know how to get the instances under def perform_create() Furthermore, I don't think my approach is not nice.

So I am considering another way, such as django signals(post_save, pre_save, etc.).

Please give any hints or tips.

Here's my models.py

class ModelA(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    fieldC = models.ForeignKey(ModelC)

class ModelB(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    fieldC = models.ForeignKey(ModelC)

views.py

class View(generics.ListCreateAPIView):
    serializer_class = ModelA_Serializer
    queryset = ModelA.objects.all()

    def perform_create(self, serializer):

        #######################################################
        ### I tried update_or_create ModelB, but it failed.####
        ### And, It's not nice way.############################
        #######################################################

        fieldC_req = int( self.request.POST.get('fieldC') )
        ModelB.objects.update_or_create(user=self.request.user, fieldC=fieldC_req)

        serializer.save(owner=self.request.user)

serializers.py

class ModelA_Serializer(serializers.ModelSerializer):
    class Meta:
        model = ModelA

Upvotes: 1

Views: 5320

Answers (2)

Aswin Kumar K P
Aswin Kumar K P

Reputation: 1102

I think you can do that with def create function in your serializers.

def create(self, validated_data):
    modelB = ModelB.objects.create(**validated_data)
    return ModelA.objects.create(**validated_data)

Disclosure: I have never tried this before.

Read more : http://www.django-rest-framework.org/tutorial/1-serialization/

Do Comment if this works.

Upvotes: 2

bakkal
bakkal

Reputation: 55448

Django signal post_save() will essentially duplicate your data

Well, first of all, you suggested the use of a Django post_save signal which will essentially duplicate the value from Model1.field to Model2.field (because post_save is called on each save).

If that is the effect you're going for, it would be a lot better if you stored that field in a single "shared" model, you don't want duplicate data, you can run into inconsistencies like that, plus it just wastes CPU and storage resources.

A REST endpoint is not necessarily tied to a (single) model

For endpoint to be well designed, it doesn't have to work on a single model or even a model for that matter.

If for your business logic you have to hit several models, there's no problem with using update_or_create on 2 models in your perform_create() that backs the POST request

Upvotes: 1

Related Questions