toastdriven / restless

A lightweight REST miniframework for Python.
http://restless.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
832 stars 107 forks source link

Late binding of Preparers #124

Open edmenendez opened 3 years ago

edmenendez commented 3 years ago

Currently, you could be left with a circular import problem if your preparer references another preparer that hasn't been defined yet and you can't change the order of the preparers to fix it.

This is a bit like when Django references another model in a ForeignKey. The Django syntax lets you put the Model directly into the ForeignKey definition or a string that references the model.

I propose supporting this syntax 'choices': CollectionSubPreparer('choice_set.all', 'survey.api.choice_preparer'),

Notice the preparer is referenced as a string instead of including it directly. The change to CollectionSubPreparer is quite simple. Something like this:

from pydoc import locate

class MyCollectionSubPreparer(CollectionSubPreparer):
    """ Override this to allow for the preparer to be a dot notation string (i.e. survey.api.question_preparer).
    """

    def prepare(self, data):
        """
        Handles passing each item in the collection data to the configured
        subpreparer.
        Uses a loop and the ``get_inner_data`` method to provide the correct
        item of the data.
        Returns a list of data as the response.
        """
        result = []

        if isinstance(self.preparer, str):
            self.preparer = locate(self.preparer)

        for item in self.get_inner_data(data):
            result.append(self.preparer.prepare(item))

        return result

I can prepare a PR that changes CollectionSubPreparer if there's interest in this change.