Пример #1
0
    def create(self, validated_data):
        """
        We have a bit of extra checking around this in order to provide
        descriptive messages when something goes wrong, but this method is
        essentially just:

            instance = ExampleModel(**validated_data)
            session.add(instance)
            session.commit()
            return object_to_dict(instance)

        If there are many to many fields present on the instance then they
        cannot be set until the model is instantiated, in which case the
        implementation is like so:

            example_relationship = validated_data.pop('example_relationship')
            instance = ExampleModel(**validated_data)
            instance.example_relationship = example_relationship
            session.add(instance)
            session.commit()
            return object_to_dict(instance)

        The default implementation also does not handle nested relationships.
        If you want to support writable nested relationships you'll need
        to write an explicit `.create()` method.
        """
        raise_errors_on_nested_writes('create', self, validated_data)

        ModelClass = self.Meta.model
        # Remove relationship instances from validated_data.
        # They are not valid arguments to the default `.create()` method,
        # as they require that the instance has already been saved
        relations = model_meta.get_relations_data(ModelClass, validated_data)

        session = settings.SQLALCHEMY_SESSION(expire_on_commit=False)
        try:
            instance = ModelClass(**validated_data)
            # After creating instance of ModelClass, just append all data,
            # which are removed earlier
            if relations:
                session.enable_relationship_loading(instance)
                for field_name, value in relations.items():
                    setattr(instance, field_name, value)

            session.add(instance)
            session.commit()
        except TypeError as exc:
            msg = ('Got a `TypeError` when calling `%s()`. '
                   'This may be because you have a writable field on the '
                   'serializer class that is not a valid argument to '
                   '`%s.objects.create()`. You may need to make the field '
                   'read-only, or override the %s.create() method to handle '
                   'this correctly.\nOriginal exception text was: %s.' %
                   (ModelClass.__name__, ModelClass.__name__,
                    self.__class__.__name__, exc))
            raise TypeError(msg)
        finally:
            session.close()

        return instance
Пример #2
0
    def put(self, request, id, *args, **kwargs):
        if not request.data:
            raise ValidationError('You must provide an updated instance.')

        session = settings.SQLALCHEMY_SESSION()
        instance = session.query(User).filter(User.id == id).first()
        if not instance:
            raise ValidationError('Object does not exist')

        serializer = UserSerializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return serializer.data
Пример #3
0
    def update(self, instance, validated_data):
        raise_errors_on_nested_writes('update', self, validated_data)

        ModelClass = self.Meta.model
        relations = model_meta.get_relations_data(ModelClass, validated_data)

        # Generate filter for getting existing object once more. Earlier,
        # We generate query to the database, because we can get relationship
        # objects, which attached to the existing object. But can't use this
        # instance further. To avoid issues with it, just get object once more
        filter_args = (getattr(ModelClass, field) == getattr(instance, field)
                       for field in model_meta.model_pk(ModelClass))

        # Simply set each attribute on the instance, and then save it.
        # Note that unlike `.create()` we don't need to treat many-to-many
        # relationships as being a special case. During updates we already
        # have an instance pk for the relationships to be associated with
        session = settings.SQLALCHEMY_SESSION(expire_on_commit=False)
        try:
            instance = session.query(ModelClass).filter(*filter_args).first()
            if not instance:
                raise ValidationError("Object does not exist.")

            for field_name, value in validated_data.items():
                setattr(instance, field_name, value)

            # Update relation objects
            if relations:
                session.enable_relationship_loading(instance)
                for field_name, value in relations.items():
                    setattr(instance, field_name, [])
                    session.refresh(instance)

                    if value:
                        setattr(instance, field_name, value)

            session.commit()
        finally:
            session.close()

        return instance
Пример #4
0
 def get(self, request, id, *args, **kwargs):
     session = settings.SQLALCHEMY_SESSION()
     instance = session.query(User).filter(User.id == id).first()
     data = AddressSerializer(instance).data
     session.close()
     return data
Пример #5
0
 def get(self, request, *args, **kwargs):
     session = settings.SQLALCHEMY_SESSION()
     users = session.query(User).all()
     data = UserSerializer(users, many=True).data
     session.close()
     return data
Пример #6
0
 def _get_session(self):
     return settings.SQLALCHEMY_SESSION()