##################
ObjectDownloadView
##################

.. py:module:: django_downloadview.views.object

:class:`ObjectDownloadView` **serves files managed in models with file fields**
such as :class:`~django.db.models.FileField` or
:class:`~django.db.models.ImageField`.

Use this view like Django's builtin
:class:`~django.views.generic.detail.DetailView`.

Additional options allow you to store file metadata (size, content-type, ...)
in the model, as deserialized fields.


**************
Simple example
**************

Given a model with a :class:`~django.db.models.FileField`:

.. literalinclude:: /../demo/demoproject/object/models.py
   :language: python
   :lines: 1-6


Setup a view to stream the ``file`` attribute:

.. literalinclude:: /../demo/demoproject/object/views.py
   :language: python
   :lines: 1-6

:class:`~django_downloadview.views.object.ObjectDownloadView` inherits from
:class:`~django.views.generic.detail.BaseDetailView`, i.e. it expects either
``slug`` or ``pk``:

.. literalinclude:: /../demo/demoproject/object/urls.py
   :language: python
   :lines: 1-7, 8-11, 27


************
Base options
************

:class:`ObjectDownloadView` inherits from
:class:`~django_downloadview.views.base.DownloadMixin`, which has various
options such as :attr:`~django_downloadview.views.base.DownloadMixin.basename`
or :attr:`~django_downloadview.views.base.DownloadMixin.attachment`.


***************************
Serving specific file field
***************************

If your model holds several file fields, or if the file field name is not
"file", you can use :attr:`ObjectDownloadView.file_field` to specify the field
to use.

Here is a model where there are two file fields:

.. literalinclude:: /../demo/demoproject/object/models.py
   :language: python
   :lines: 1-6, 7

Then here is the code to serve "another_file" instead of the default "file":

.. literalinclude:: /../demo/demoproject/object/views.py
   :language: python
   :lines: 1-4, 8-11


**********************************
Mapping file attributes to model's
**********************************

Sometimes, you use Django model to store file's metadata. Some of this metadata
can be used when you serve the file.

As an example, let's consider the client-side basename lives in model and not
in storage:

.. literalinclude:: /../demo/demoproject/object/models.py
   :language: python
   :lines: 1-6, 8

Then you can configure the :attr:`ObjectDownloadView.basename_field` option:

.. literalinclude:: /../demo/demoproject/object/views.py
   :language: python
   :lines: 1-4, 13-17

.. note::

   ``basename`` could have been a model's property instead of a ``CharField``.

See details below for a full list of options.


*************
API reference
*************

.. autoclass:: ObjectDownloadView
   :members:
   :undoc-members:
   :show-inheritance:
   :member-order: bysource
