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
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
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
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
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
def _get_session(self): return settings.SQLALCHEMY_SESSION()