def handle_nested_serializer(self, resource, field, field_name, request): serializer_field = get_related_field(field) if hasattr(serializer_field, "opts"): model = serializer_field.opts.model else: model = serializer_field.Meta.model resource_type = self.model_to_resource_type(model) linked_ids = self.dict_class() links = self.dict_class() linked = self.dict_class() linked[resource_type] = [] if is_related_many(field): items = resource[field_name] else: items = [resource[field_name]] obj_ids = [] resource.serializer = serializer_field for item in items: converted = self.convert_resource(item, resource, request) linked_obj = converted["data"] linked_ids = converted.pop("linked_ids", {}) if linked_ids: linked_obj["links"] = linked_ids obj_ids.append(converted["data"]["id"]) field_links = self.prepend_links_with_name( converted.get("links", {}), resource_type) field_links[field_name] = { "type": resource_type, } if "href" in converted["data"]: url_field_name = api_settings.URL_FIELD_NAME url_field = serializer_field.fields[url_field_name] field_links[field_name]["href"] = self.url_to_template( url_field.view_name, request, field_name, ) links.update(field_links) linked[resource_type].append(linked_obj) if is_related_many(field): linked_ids[field_name] = obj_ids else: linked_ids[field_name] = obj_ids[0] return {"linked_ids": linked_ids, "links": links, "linked": linked}
def handle_related_field(self, resource, field, field_name, request): links = self.dict_class() linked_ids = self.dict_class() related_field = get_related_field(field) model = self.model_from_obj(related_field) resource_type = self.model_to_resource_type(model) if field_name in resource: links[field_name] = { "type": resource_type, } if is_related_many(field): link_data = [ encoding.force_text(pk) for pk in resource[field_name]] elif resource[field_name]: link_data = encoding.force_text(resource[field_name]) else: link_data = None linked_ids[field_name] = link_data return {"linked_ids": linked_ids, "links": links}
def convert_resource(self, resource, view): serializer_data = view.get_serializer(instance=None) fields = serializer_data.fields links = {} if "links" in resource: links = resource["links"] del resource["links"] for field_name, field in six.iteritems(fields): if field_name not in links: continue related_field = get_related_field(field) if isinstance(related_field, relations.HyperlinkedRelatedField): if is_related_many(field): pks = links[field_name] model = related_field.queryset.model resource[field_name] = [] for pk in pks: obj = model(pk=pk) try: url = related_field.to_representation(obj) except AttributeError: url = related_field.to_native(obj) resource[field_name].append(url) else: pk = links[field_name] model = related_field.queryset.model obj = model(pk=pk) try: url = related_field.to_representation(obj) except AttributeError: url = related_field.to_native(obj) resource[field_name] = url else: resource[field_name] = links[field_name] return resource
def url_to_pk(self, url_data, field): if is_related_many(field): try: obj_list = field.to_internal_value(url_data) except AttributeError: obj_list = [field.from_native(url) for url in url_data] return [encoding.force_text(obj.pk) for obj in obj_list] if url_data: try: obj = field.to_internal_value(url_data) except AttributeError: obj = field.from_native(url_data) return encoding.force_text(obj.pk) else: return None