Comment sérialiser django-mptt
arbres dans Tastypie
? Je veux utiliser django-mptt
cache_tree_children()
. J'ai essayé d'appliquer dans différents hooks Tastypie, mais cela génère une erreur.Sérialisation d'arbres django-mptt dans Tastypie
Répondre
Voici comment je l'ai résolu:
class MenuResource(ModelResource):
parent = fields.ForeignKey('self', 'parent', null=True)
class Meta:
serializer = PrettyJSONSerializer()
queryset = Menu.objects.all().select_related('parent')
include_resource_uri = False
fields = ['name']
def get_child_data(self, obj):
data = {
'id': obj.id,
'name': obj.name,
}
if not obj.is_leaf_node():
data['children'] = [self.get_child_data(child) \
for child in obj.get_children()]
return data
def get_list(self, request, **kwargs):
base_bundle = self.build_bundle(request=request)
objects = self.obj_get_list(bundle=base_bundle,
**self.remove_api_resource_names(kwargs))
sorted_objects = self.apply_sorting(objects, options=request.GET)
paginator = self._meta.paginator_class(
request.GET, sorted_objects,
resource_uri=self.get_resource_uri(), limit=self._meta.limit,
max_limit=self._meta.max_limit,
collection_name=self._meta.collection_name
)
to_be_serialized = paginator.page()
from mptt.templatetags.mptt_tags import cache_tree_children
objects = cache_tree_children(objects)
bundles = []
for obj in objects:
data = self.get_child_data(obj)
bundle = self.build_bundle(data=data, obj=obj, request=request)
bundles.append(self.full_dehydrate(bundle))
to_be_serialized[self._meta.collection_name] = bundles
to_be_serialized = self.alter_list_data_to_serialize(request,
to_be_serialized)
return self.create_response(request, to_be_serialized)
Si vous ne l'utilisez, vous pouvez simplement pagination prendre cette partie dehors. C'est ce que j'ai fait.
Sans la méthode cache_tree_children
vous pourriez probablement avoir vos enfants sérialisé simplement brancher un ToManyField
avec full=True
pointage à la propriété children
:
class MenuResource(ModelResource):
children = fields.ToManyField('self', 'children', null=True, full=True)
parent = fields.ToOneField('self', 'parent', null=True)
class Meta:
queryset = Menu.objects.all()
Pour implémenter la fonction cache_tree_children
vous pouvez écrire votre propre ToManyField
sous-classe qui remplace la fonction standard dehydrate
. S'il vous plaît noter que je ne testé cette solution très superficielle:
def dehydrate(self, bundle):
if not bundle.obj or not bundle.obj.pk:
if not self.null:
raise ApiFieldError("The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj)
return []
the_m2ms = None
previous_obj = bundle.obj
attr = self.attribute
if isinstance(self.attribute, basestring):
attrs = self.attribute.split('__')
the_m2ms = bundle.obj
for attr in attrs:
previous_obj = the_m2ms
try:
the_m2ms = getattr(the_m2ms, attr, None)
except ObjectDoesNotExist:
the_m2ms = None
if not the_m2ms:
break
elif callable(self.attribute):
the_m2ms = self.attribute(bundle)
if not the_m2ms:
if not self.null:
raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr))
return []
self.m2m_resources = []
m2m_dehydrated = []
# There goes your ``cache_tree_children``
for m2m in cache_tree_children(the_m2ms.all()):
m2m_resource = self.get_related_resource(m2m)
m2m_bundle = Bundle(obj=m2m, request=bundle.request)
self.m2m_resources.append(m2m_resource)
m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource))
return m2m_dehydrated
L'un des principaux avantages de cette méthode est que vous n'avez pas à se soucier de détail/liste des contraintes de vue/différences plus. Vous pouvez même paramétrer cet aspect de votre ressource plus bas jusqu'à ce que vous ayez un comportement par défaut qui corresponde à vos besoins. Basé sur le terrain, c'est. Ce que je pense est cool.
- 1. TastyPie Sérialisation pendant déshydrater
- 2. Tastypie sérialisation Modèle de champ virtuel
- 3. Clé étrangère dans tastypie
- 4. Modèles dynamiques dans tastypie
- 5. Ressource multiple dans tastypie
- 6. tastypie: save_m2m
- 7. Django Tastypie
- 8. ToManyFields imbriqués dans django-tastypie
- 9. champs et exclure dans tastypie
- 10. Signification de Django-Tastypie?
- 11. REST urls avec tastypie
- 12. Authentification tastypie/réponse personnalisée
- 13. Filtre de négation Tastypie
- 14. django-tastypie ToOneField
- 15. tastypie problèmes de registre
- 16. Django tastypie et GenericForeignKey
- 17. Tastypie: Filtrage par ToManyField
- 18. Tastypie - Queryset ou filtres
- 19. TastyPie et propriétés
- 20. inverse relation ToManyField Tastypie
- 21. Aucun module nommé urls dans django-tastypie
- 22. Comment utiliser OR dans Django Tastypie
- 23. Comment hydrater une resource_uri dans django-tastypie?
- 24. Impossible de faire fonctionner ToMany dans Tastypie
- 25. Comment retourner un seul champ dans tastypie?
- 26. gérer plusieurs paramètres de requête dans tastypie
- 27. Tri dans tastypie pour non-orm (mongodb)
- 28. Comment gérer les actions dans Django/Tastypie?
- 29. Quoi de neuf dans django-tastypie 0.10
- 30. Tastypie build_filters accès tp request.user