Commit ab703a09 authored by chris's avatar chris
Browse files

Repackaged. Fixed Python3 unittest due to South bug. Updated docs.

parent 5a9e7169
django-database-files
=====================
Django Database Files 3000
==========================
django-database-files is a storage system for Django that stores uploaded files
in the database.
WARNING: It is generally a bad idea to serve static files from Django,
but there are some valid use cases. If your Django app is behind a caching
reverse proxy and you need to scale your application servers, it may be
simpler to store files in the database.
This is a storage system for Django that stores uploaded
files in the database. Files can be served from the database
(usually a bad idea), the file system, or a CDN.
Installation
------------
python setup.py install
Or via pip with:
Simply install via pip with:
pip install django-database-files
You can run unittests with:
python setup.py test
You can run unittests for a specific Python version using the `pv` parameter
like:
python setup.py test --pv=3
pip install django-database-files-3000
Usage
-----
......@@ -58,3 +43,37 @@ To delete all files in the database and file system not referenced by any model
fields, run:
python manage.py database_files_cleanup
Settings
-------
* `DB_FILES_AUTO_EXPORT_DB_TO_FS` = `True`|`False` (default `True`)
If true, when a file is uploaded or read from the database, a copy will be
exported to your media directory corresponding to the FileField's upload_to
path, just as it would with the default Django file storage.
If false, the file will only exist in the database.
* `DATABASE_FILES_URL_METHOD` = `URL_METHOD_1`|`URL_METHOD_1` (default `URL_METHOD_1`)
Defines the method to use when rendering the web-accessible URL for a file.
If `URL_METHOD_1`, assumes all files have been exported to the filesystem and
uses the path corresponding to your `settings.MEDIA_URL`.
If `URL_METHOD_2`, uses the URL bound to the `database_file` view
to dynamically lookup and serve files from the filesystem or database.
Development
-----------
You can run unittests with:
python setup.py test
You can run unittests for a specific Python version using the `pv` parameter
like:
python setup.py test --pv=3.2
\ No newline at end of file
VERSION = (0, 2, 1)
VERSION = (0, 3, 0)
__version__ = '.'.join(map(str, VERSION))
\ No newline at end of file
......@@ -135,6 +135,10 @@ class DatabaseFilesViewTestCase(TestCase):
def test_reading_file(self):
self.assertEqual(File.objects.count(), 1)
response = self.client.get('/files/1.txt')
self.assertEqual(response.content, b'1234567890')
if hasattr(response, 'streaming_content'):
content = list(response.streaming_content)[0]
else:
content = response.content
self.assertEqual(content, b'1234567890')
self.assertEqual(response['content-type'], 'text/plain')
self.assertEqual(response['content-length'], '10')
......@@ -6,5 +6,10 @@ except ImportError:
from django.conf.urls import patterns, url
urlpatterns = patterns('',
url(r'^files/(?P<name>.+)$', 'database_files.views.serve', name='database_file'),
# url(r'^files/(?P<name>.+)$',
# 'database_files.views.serve',
# name='database_file'),
url(r'^files/(?P<name>.+)$',
'database_files.views.serve_mixed',
name='database_file'),
)
import base64
import os
from django.conf import settings
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.cache import cache_control
......@@ -22,15 +23,16 @@ def serve(request, name):
response['Content-Length'] = f.size
return response
def serve_mixed(request, path, document_root):
def serve_mixed(request, name, document_root=None):
"""
First attempts to serve the file from the filesystem,
then tries the database.
"""
document_root = document_root or settings.MEDIA_ROOT
try:
# First attempt to serve from filesystem.
return django_serve(request, path, document_root)
return django_serve(request, name, document_root)
except Http404:
# Then try serving from database.
return serve(request, path)
return serve(request, name)
\ No newline at end of file
......@@ -5,13 +5,26 @@ from setuptools import setup, find_packages, Command
import database_files
def get_reqs(test=False):
try:
from pypandoc import convert
read_md = lambda f: convert(f, 'rst')
except ImportError:
print("Warning: pypandoc module not found, could not convert "
"Markdown to RST")
read_md = lambda f: open(f, 'r').read()
def get_reqs(test=False, pv=None):
reqs = [
'Django>=1.4',
'six>=1.7.2',
]
if test:
reqs.append('South>=0.8.4')
#TODO:remove once Django 1.7 south integration becomes main-stream?
if not pv:
reqs.append('South>=1.0')
elif pv <= 3.2:
# Note, South dropped Python3 support after 0.8.4...
reqs.append('South==0.8.4')
return reqs
class TestCommand(Command):
......@@ -27,9 +40,13 @@ class TestCommand(Command):
def initialize_options(self):
self.name = None
self.virtual_env_dir = './.env%s'
self.virtual_env_dir = '.env%s'
self.pv = 0
self.versions = [2.7, 3]
self.versions = [
2.7,
3,
#3.3,#TODO?
]
def finalize_options(self):
pass
......@@ -39,16 +56,17 @@ class TestCommand(Command):
kwargs = dict(virtual_env_dir=virtual_env_dir, pv=pv)
if not os.path.isdir(virtual_env_dir):
cmd = 'virtualenv -p /usr/bin/python{pv} {virtual_env_dir}'.format(**kwargs)
#print(cmd)
print(cmd)
os.system(cmd)
cmd = '. {virtual_env_dir}/bin/activate; easy_install -U distribute; deactivate'.format(**kwargs)
cmd = '{virtual_env_dir}/bin/easy_install -U distribute'.format(**kwargs)
print(cmd)
os.system(cmd)
for package in get_reqs(test=True):
for package in get_reqs(test=True, pv=float(pv)):
kwargs['package'] = package
cmd = '. {virtual_env_dir}/bin/activate; pip install -U {package}; deactivate'.format(**kwargs)
#print(cmd)
cmd = '{virtual_env_dir}/bin/pip install -U {package}'.format(**kwargs)
print(cmd)
os.system(cmd)
def run(self):
......@@ -59,25 +77,34 @@ class TestCommand(Command):
for pv in versions:
self.build_virtualenv(pv)
kwargs = dict(pv=pv, name=self.name)
kwargs = dict(
pv=pv,
virtual_env_dir=self.virtual_env_dir % pv,
name=self.name)
if self.name:
cmd = '. ./.env{pv}/bin/activate; django-admin.py test --pythonpath=. --settings=database_files.tests.settings database_files.tests.tests.{name}; deactivate'.format(**kwargs)
cmd = '{virtual_env_dir}/bin/django-admin.py test --pythonpath=. --settings=database_files.tests.settings database_files.tests.tests.{name}'.format(**kwargs)
else:
cmd = '. ./.env{pv}/bin/activate; django-admin.py test --pythonpath=. --settings=database_files.tests.settings database_files.tests; deactivate'.format(**kwargs)
cmd = '{virtual_env_dir}/bin/django-admin.py test --pythonpath=. --settings=database_files.tests.settings database_files.tests'.format(**kwargs)
print(cmd)
ret = os.system(cmd)
if ret:
return
try:
long_description = read_md('README.md')
except IOError:
long_description = ''
setup(
name='django-database-files',
name='django-database-files-3000',
version=database_files.__version__,
description='A storage system for Django that stores uploaded files in both the database and file system.',
author='Ben Firshman',
author_email='ben@firshman.co.uk',
url='http://github.com/bfirsh/django-database-files/',
long_description=long_description,
author='Chris Spencer',
author_email='chrisspen@gmail.com',
url='http://github.com/chrisspen/django-database-files-3000',
packages=[
'database_files',
'database_files.management',
......@@ -95,6 +122,7 @@ setup(
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.0',
'Programming Language :: Python :: 3.2',
],
install_requires = get_reqs(),
cmdclass={
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment