wlanslovenija / django-tastypie-mongoengine

MongoEngine support for django-tastypie.
Other
73 stars 59 forks source link

Option to get related resource_uri with polymorphic resources #38

Closed leo-naeka closed 11 years ago

leo-naeka commented 11 years ago

Currently, when using polymorphic resources, we have resource_uri's mapped according to the polymorphic resource's resource_name. This is perfect and the good behaviour when we want to group multiple specific resources into a common "entity". But in some cases (and especially when you use js frameworks like emberjs/data -our case- or backbone) it is useful to get the targetted object with its original (related) resource_uri. Finally, the polymorphic resource acts like a "transparent proxy".

Please, look at the tests and how I have implemented it.

If you're satisfied, I'll add some doc and more tests for this option.

Signed-off-by: Léo S. leo@naeka.fr

mitar commented 11 years ago

I am not sure if I understand the problem correctly. If I understand correctly, you want that ContactResource be polymorphic class, while IndividualResource and CompanyResource be specific classes, and that resource_uri when accessing through ContactResource, point to IndividualResource and CompanyResource?

Why do you want IndividualResource and CompanyResource resources to be available in the first place? Why not just use ContactResource and polymorphic feature of django-tastypie-mongoengine?

Cosmetic comment: I am not sure if ApiNameMixin is correct place for this code.

leo-naeka commented 11 years ago

You've understood correctly.

In my case, I don't care of the ContactResource, I do not expose it through the API. But I use it to dehydrate correctly references to either IndividualResource or CompanyResource in other resources.

My client should not care about the resource_type and get the correct resource (full or not) directly. It should only care of Individual and Company and doesn't know Contact, this is backend use of inheritance.

mitar commented 11 years ago

But why you need then Contact in the first place? Why not just have Contact be abstract and have two documents and two resources? Or even not having it abstract, but simple having only IndividualResource and CompanyResource as it is defined now? Because you want to make a reference in ContactGroupResource to any of those?

But you could use GenericReferenceField on MongoEngine to get this, no?

mitar commented 11 years ago

(Just brainstorming here, trying to understand the landscape of possible ways to address this.)

leo-naeka commented 11 years ago

On the mongoengine layer, using a ReferenceField on the base model instead of a GenericReferenceField ensures that the reference is one of the sub-models.

But even if consider two separated resources : IndividualResource and CompanyResource, when I want to transparently refer to it in another resource, how can I do that ?

(Don't worry, also in brainstorming mode)

mitar commented 11 years ago

You could always create your own GenericReferenceField subclass which would limit allowed documents (there is nothing at MongoDB level to prevent arbitrary links, this are all just MongoEngine checks anyway, I believe).

I never used GenericReferenceField field in resource. But it should probably be possible to do. And then you would just make a reference to any resource_uri you want.

mitar commented 11 years ago

BTW, one general issue I have with this is: is it really callee who should define where does resource_uri point? Or it should be caller?

mitar commented 11 years ago

One other thing; why do you need two resource endpoints, why is not enough to have only contacts and use polymorphic features of this package to get wanted resources? Your JS libraries do not support that?

leo-naeka commented 11 years ago

Yeah, those libraries may support that using adapters. But that's not the expected behavior in my case: I need multiple endpoints for segmentation, my resources are quite different and should be acceeded through their own endpoint, never through a common one.

There is two ways to refers differenciated resources:

mitar commented 11 years ago

OK. Sorry for being late in getting back to this. :-( This life is just too busy.

OK, I understand your need but I believe the approach is not nice. You are overriding resource_name when you just want resource uri to point differently. I would be more for approach of overriding resource uri method.

I still believe this should be simply done with custom field class. It would much less hackish and just reusing existing code.

mitar commented 11 years ago

OK. After some looking around, it seems this is really the most reasonable approach. :-) So please add more tests, documentation and I have just some cosmetic requests:

I checked code and it seems there will be no problems with overriding that resource name.

Thanks for all you effort!

leo-naeka commented 11 years ago

Regarding the registered check, I'm agree with you. Unfortunately, the only way to check that is by checking in the Api registry. Neither the Api or the registry can be acceeded through the resource. Anyway, we could use an inherited Api class which could store a is_registered boolean flag on the resource on register/unregister - cf. tastypie/api.py#L29-L62

Just tell me what's your opinion about that, for now I'll add some doc.

mitar commented 11 years ago

I see two other options:

I like the first option a bit more. Because it is all about URIs, so if it cannot be found, the preferred one, we fall back to backup.

mitar commented 11 years ago

Just to know: I do not get any notification when somebody just updates the pull request without any comment here. Sorry that I missed that you updated the pull request a while ago. :-( Please comment something here, like "updated", in the future.

mitar commented 11 years ago

Sorry for delay.

mitar commented 11 years ago

And thanks for the contribution.