Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using ObjectDownloadView to serve a file if it exists, and create the file if it does not #84

Open
quietlyconfident opened this issue Mar 14, 2014 · 0 comments

Comments

@quietlyconfident
Copy link
Contributor

New Feature / Documentation proposals

I'm using ObjectDownloadView to serve files represented by file_fields in my model. Creating the file is costly (computationally) and so I don't want to do VirtualDownloadView and re-create it each time. Thus , sometimes the file exists, and sometimes it does not. What I would like to do is call one ObjectDownloadView in all cases, and if the file does not exist, create it on the fly before the response. This will make that one response slow, but after that it should be snappy.

So, I subclassed the get_file() command as so:

class CreateOnDemandDownloadView(ObjectDownloadView):
    def get_file(self):
        file_instance = getattr(self.object, self.file_field)
        if not file_instance:
            self.object.create_downloadable_file()
        return super(CreateOnDemandDownloadView,self).get_file(self)

Having this example in the documentation may help others, or perhaps it is too mundane.

Similarly, I have a case that almost fits the ObjectDownloadView use case for basename_field, which is that I want the filename to be constructed from a field on the object, but then changed. So I subclassed get_basename in the following manner:

class PdfDownloadView(ObjectDownloadView):
    def get_basename(self):
        model_field = getattr(self, 'basename_field', False)
        if model_field:
            basename = slugify(getattr(self.object, model_field)) + ".PDF"
        return basename

In each of these cases, it occurred to me that the various views might benefit from the ability to pass in a function that modifies their behavior, as an argument, rather than have to subclass the view itself. In other words, extending the API for ObjectDownloadView to permit things like:

# Define transform function for basename
def pdf_esque_filename(value):
    return slugify(value) + ".PDF"

# Define ability to call methods of model instances
def createFile(object):
    object.callable_method_of_object()

pdfDownloadView = ObjectDownloadView.as_view(model=Document,file_field='my_file_field',file_not_found_method=createFile,basename_field='some_text_field',basename_transform=pdf_esque_filename)

This doesn't accomplish anything that you can't do with subclassing. But it would reduce repetition if you want to use various transforms &c in different combinations with different views / objects / etc.

@benoitbryon benoitbryon added this to the Later milestone Jun 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants