def api_update(self, request, id): try: attrs = self.clean(self.deserialize(request.body)) except ValueError as e: self.logger.info("Bad request: %r (%s)", request.body, e) return self.response(str(e), status=self.BAD_REQUEST) qs = self.queryset(request).filter(**{self.pk: id}) if self.exclude_fields: qs = qs.exclude(*self.exclude_fields) o = qs.first() if not o: return HttpResponse("", status=self.NOT_FOUND) if self.has_uuid and not attrs.get("uuid") and not o.uuid: attrs["uuid"] = uuid.uuid4() if hasattr(o, "tags") and attrs.get("tags"): old_tags = set(o.tags) if o.tags else set() new_tags = set(attrs["tags"]) if attrs["tags"] else set() for t in old_tags - new_tags: self.logger.info("Unregister Tag: %s" % t) Tag.unregister_tag(t, repr(self.model)) for t in new_tags - old_tags: self.logger.info("Register Tag: %s" % t) Tag.register_tag(t, repr(self.model)) # @todo: Check for duplicates for k in attrs: if not self.has_field_editable(k): continue if k != self.pk and "__" not in k: setattr(o, k, attrs[k]) try: o.save() except ValidationError as e: return self.response({"message": str(e)}, status=self.BAD_REQUEST) # Reread result o = self.model.objects.get(**{self.pk: id}) if request.is_extjs: r = {"success": True, "data": self.instance_to_dict(o)} else: r = self.instance_to_dict(o) return self.response(r, status=self.OK)
def api_update(self, request, id): if self.site.is_json(request.META.get("CONTENT_TYPE")): attrs, m2m_attrs = self.split_mtm(self.deserialize(request.body)) else: attrs, m2m_attrs = self.split_mtm(self.deserialize_form(request)) attrs, file_attrs = self.split_file(attrs) try: attrs = self.clean(attrs) except ValueError as e: self.logger.info( "Bad request: %r (%s)", request.body if not request._read_started else request, e ) return self.render_json( {"success": False, "message": "Bad request", "traceback": str(e)}, status=self.BAD_REQUEST, ) # Find object try: o = self.queryset(request).get(**{self.pk: int(id)}) except self.model.DoesNotExist: return HttpResponse("", status=self.NOT_FOUND) # Tags if hasattr(o, "tags") and attrs.get("tags"): old_tags = set(o.tags) if o.tags else set() new_tags = set(attrs["tags"]) if attrs["tags"] else set() for t in old_tags - new_tags: self.logger.info("Unregister Tag: %s" % t) Tag.unregister_tag(t, repr(self.model)) for t in new_tags - old_tags: self.logger.info("Register Tag: %s" % t) Tag.register_tag(t, repr(self.model)) # Update attributes for k, v in attrs.items(): if ( self.secret_fields and k in self.secret_fields and not self.has_secret() and self.has_field_editable(k) ): continue setattr(o, k, v) # Run models validators try: o.clean_fields() except ValidationError as e: e_msg = [] for f in e.message_dict: e_msg += ["%s: %s" % (f, "; ".join(e.message_dict[f]))] return self.render_json( {"status": False, "message": "Validation error: %s" % " | ".join(e_msg)}, status=self.BAD_REQUEST, ) # Check permissions if not self.can_create(request.user, o): return self.render_json( {"status": False, "message": "Permission denied"}, status=self.FORBIDDEN ) # Save try: o.save() if m2m_attrs: self.update_m2ms(o, m2m_attrs) if file_attrs: # Save uploaded file self.update_file(request.FILES, o, file_attrs) except IntegrityError: return self.render_json( {"success": False, "message": "Integrity error"}, status=self.CONFLICT ) if request.is_extjs: r = {"success": True, "data": self.instance_to_dict(o)} else: r = self.instance_to_dict(o) return self.response(r, status=self.OK)