Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override default create method in django-rest-framework

I have a model which uses a different create method in the manager. How do I override this method so that the post method in ListCreateAPIView uses the method I've written instead of the default method. Here's the method.

class WeddingInviteManager(models.Manager):


 def create(self, to_user, from_user, wedding):
      wedding_invitation =  self.create(from_user=from_user,to_user=to_user, 
                                        wedding=wedding)
      notification.send([self.to_user], 'wedding_invite',{'invitation':wedding_invitation})

      return wedding_invitation
like image 489
zacmwa Avatar asked Sep 04 '14 13:09

zacmwa


1 Answers

I suppose the reason for doing the is actually the notification system.

I would recommend doing something like this instead:

class MyModel(models.Model):
    ...
    def save(self, silent=False, *args, **kwargs):
        # Send notification if this is a new instance that has not been saved
        # before:
        if not silent and not self.pk:
            notification.send([self.to_user], 'wedding_invite', {'invitation': self})

        return super(MyModel, self).save(*args, **kwargs)

But if you must, this is (in theory) how you do it (code not tested):

from rest_framework import serializers, viewsets

class MyModelSerializer(serializers.ModelSerializer):
    def save_object(self, obj, **kwargs):
        """
        Save the deserialized object.
        """
        if getattr(obj, '_nested_forward_relations', None):
            # Nested relationships need to be saved before we can save the
            # parent instance.
            for field_name, sub_object in obj._nested_forward_relations.items():
                if sub_object:
                    self.save_object(sub_object)
                setattr(obj, field_name, sub_object)

        #####  EDITED CODE #####
        if obj.pk:
            obj.save(**kwargs)
        else:
            # Creating a new object. This is silly.
            obj = MyModel.objects.create(obj.to_user, obj.from_user, obj.wedding)
        ##### /EDITED CODE #####

        if getattr(obj, '_m2m_data', None):
            for accessor_name, object_list in obj._m2m_data.items():
                setattr(obj, accessor_name, object_list)
            del(obj._m2m_data)

        if getattr(obj, '_related_data', None):
            related_fields = dict([
                (field.get_accessor_name(), field)
                for field, model
                in obj._meta.get_all_related_objects_with_model()
            ])
            for accessor_name, related in obj._related_data.items():
                if isinstance(related, RelationsList):
                    # Nested reverse fk relationship
                    for related_item in related:
                        fk_field = related_fields[accessor_name].field.name
                        setattr(related_item, fk_field, obj)
                        self.save_object(related_item)

                    # Delete any removed objects
                    if related._deleted:
                        [self.delete_object(item) for item in related._deleted]

                elif isinstance(related, models.Model):
                    # Nested reverse one-one relationship
                    fk_field = obj._meta.get_field_by_name(accessor_name)[0].field.name
                    setattr(related, fk_field, obj)
                    self.save_object(related)
                else:
                    # Reverse FK or reverse one-one
                    setattr(obj, accessor_name, related)
            del(obj._related_data)


class MyModelViewSet(viewsets.ModelViewSet):
    serializer_class = MyModelSerializer
    queryset = MyModel.objects.all()
like image 177
demux Avatar answered Oct 19 '22 00:10

demux