mardi 14 mai 2019

Ember - saving Foreign Key relationship, using Django DRF (JSON API)

I have the following models for Order, User and PaymentMethod.

In Django, they are defined (fields excluded for brevity) as follows:

class User:
    email = models.EmailField(unique=True)
    class JSONAPIMeta:
        resource_name = 'users'

class PaymentMethod:
    name = models.CharField(max_length=255, unique=True)
    class JSONAPIMeta:
        resource_name='payment-methods'

class Order:
    user = models.ForeignKey(User,blank=True,null=True,on_delete=models.SET_NULL,related_name="user_orders")
    payment_method = models.ForeignKey(PaymentMethod, null=True, on_delete=models.SET_NULL, related_name="order_payment_methods")

    class JSONAPIMeta:
        resource_name = 'orders'

I have serializer classes as follows:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id','email')

class PaymentMethodSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentMethod
        fields = ('id', 'name')

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ('id','user','payment_method')

The viewsets are as follows:

from rest_framework import viewsets

class OrderViewSet(viewsets.ModelViewSet):
    queryset = Order.objects.all().order_by('id')
    serializer_class = OrderSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

class PaymentMethodViewSet(viewsets.ModelViewSet):
    queryset = PaymentMethod.objects.all()
    serializer_class = PaymentMethodSerializer

In my Ember models, I the relationships are simple (I have created a serializers which transforms paymentMethod in Ember to payment_method for Django)

user:

export default DS.Model.extend({
    email: DS.attr('string'),
});

order:

export default DS.Model.extend({
    user: DS.belongsTo('user'),
    paymentMethod: DS.belongsTo('payment-method'),
});

payment-method:

export default DS.Model.extend({
    name: DS.attr('string'),
    orderPaymentMethods: DS.hasMany('order')
});

In Ember, I save the order as follows, having already obtained objects for the user and payment method:

let orderData = {
   user: userObject,
   paymentMethod: paymentMethodObject
};

this.store.createRecord('order', orderData).save().then((order) => {
    ... redirect etc
});

This saves the order fine with regard to the user object, but it's not saving the payment method relationship.

Upon inspection of the create method in the Order serializer, the payment method object is not present.

To fix this, I tried overriding the create method of the order view set as follows:

 def create(self, request, *args, **kwargs):
     payment_method_id = request.data.get('payment-method').get('id')
     payment_method = PaymentMethod.objects.get(id=payment_method_id)

     s = OrderSerializer(data=request.data)
     if s.is_valid():
         s.save(payment_method=payment_method)
     return JsonResponse({"data":request.data})

This works - and saves the payment method relationship, but I need to return a valid JSON API response, which the above is not.

There has to be an easier way for me to save the payment method relationship?

Any help much appreciated!




Aucun commentaire:

Enregistrer un commentaire