#5361: Support pluggable backends for FileField
------------------------------------------------------------+---------------
Reporter: Marty Alchin <[EMAIL PROTECTED]> | Owner:
Gulopine
Status: new | Milestone:
1.0 beta
Component: Database wrapper | Version:
SVN
Resolution: | Keywords:
Stage: Accepted | Has_patch: 1
Needs_docs: 1 | Needs_tests: 0
Needs_better_patch: 1 |
------------------------------------------------------------+---------------
Changes (by Gulopine):
* needs_better_patch: 0 => 1
* needs_docs: 0 => 1
Comment:
Regarding 5361-r8012.diff: this patch covers a lot of ground, so here are
some details. The main goal of this version of the patch was to
consolidate things a bit. After [7814] went in, it was clear that there'd
be a lot of almost-duplication, and I wanted to centralize as much as I
could, so all file operations can share as much code as possible. Most of
the major changes are the product of that consolidation, and I hope it
makes things easier all around.
* Everything from `django.core.filestorage` has been moved into
`django.core.files`, so there aren't two file-related packages lying
around.
* With a single package for more file stuff than just storage, I put all
the storage-related items into `django.core.files.storage`. This means
there's no great place to add extra backends in the future. The idea now
is that Django itself will just have filesystem storage, and others will
be provided by extra apps. This probably means #6390 will be closed as
wontfix, but there's no official word on that yet.
* All representations of files are now based on
`django.core.files.base.File`, which provides most features. Subclasses
can override `__init__` to change how they're constructed, override other
methods to customize behavior, and add new methods entirely, but they
should all use that same base class. It's functional enough to be used on
its own in some cases, but most will probably need a subclass. The
existing uploaded file stuff has also been modified to use this base
class.
* Specific file types are now implemented as mixins, with `ImageFile`
located at `django.core.files.images`. That module also contains
`get_image_dimensions` that used to be at `django.utils.images`, with an
import and a `DeprecationWarning` left at the old location. The mixin
thing allows for more intelligent combinations of classes. Essentially,
each backend can provide its own `File` class, while each `FileField`
subclass can provide its own mixin, or they can be used in other cases
too, even without models. It's all about flexibility. There's probably
some more work to be done on that, though, so I'd especially like some
tires to be kicked.
* The backend protocol changed slightly, such that `open()` shouldn't be
overridden by new backends. `open()` now takes a `mixin` argument,
relating to the above point, and it calls `_open()` behind the scenes to
get the backend-related file, which is then combined with the provided
mixin to produce the resultant `File` object. Backends should only
implement `_open()`, and that method works exactly like `open()` did up to
this patch. I'm open to API improvements on this, but I think it's the
best way to approach it, without requiring backends to deal with the mixin
thing directly.
* The object returned when you reference `instance.field` is now a legit
`File` subclass on its own, without having to call `.open()` explicitly.
There are almost certainly some hidden problems with this approach, and I
haven't worked out a good way to test it thoroughly. I'm particularly
concerned with caching file references and properly passing things through
to remote backends, like S3 or !MogileFS. I'm almost certain there are
some issues when referencing the file multiple times using
`instance.field.read()`, for instance, because the object gets regenerated
each time it's accessed. This can be worked around, but to keep caching
working, it requires some trickiness that I'd like to avoid if I can. If
there are significant issues though, the trickiness is definitely the
lesser of two evils.
* `RemoteFile` has been relegated to `django.core.files.remote`, and it's
not really used internally, but it's there as a base for remote storage
systems to use. It probably needs some updating to work properly with
everything else, but I need somebody who's working on a remote backend to
kick the tires on it a bit to know exactly what love it needs. You know
who you are.
In general, I'm very happy with how the patch looks and works now, but I'm
still a bit concerned with how well it addresses the needs of custom
backends. I know a few people following this patch are working on some,
and I'd greatly appreciate it if you can spare some time to update to the
newest patch, and modify your backends accordingly. Please report back
what you've found, what works, what doesn't, and what ideas you have to
improve the interface.
Also, this patch doesn't include any documentation, because it hasn't yet
been updated to the newest changes described above. I'll be working on
that this week, but I wanted to get the code up so people can start
working with it and get feedback. It's on the way, though. I may have
missed a few changes, and if I have, I apologize, and I'm glad to explain
anything that doesn't make sense.
--
Ticket URL: <http://code.djangoproject.com/ticket/5361#comment:71>
Django Code <http://code.djangoproject.com/>
The web framework for perfectionists with deadlines
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---