# Path: buckets/fields.py
# class S3FileField(models.Field):
#     """ Stores and provides access to a file stored in an AWS S3 bucket. To set
#         the value of an `S3FileField` you usually provide the URL of the file
#         in the bucket. Internally this URL is converted to a `S3File`, which
#         provides access to the actual file on S3."""
#     attr_class = S3File
#     descriptor_class = S3FileDescriptor
# 
#     description = _("A file stored in an AWS S3 buckets.")
# 
#     def __init__(self, upload_to='', storage=None, accepted_types=None,
#                  *args, **kwargs):
#         self.storage = storage or default_storage
#         self.upload_to = upload_to
#         self.accepted_types = accepted_types
# 
#         kwargs['max_length'] = kwargs.get('max_length', 200)
#         super(S3FileField, self).__init__(*args, **kwargs)
# 
#     def get_internal_type(self):
#         return 'CharField'
# 
#     def contribute_to_class(self, cls, name, **kwargs):
#         super(S3FileField, self).contribute_to_class(cls, name, **kwargs)
#         setattr(cls, self.name, self.descriptor_class(self))
# 
#     def deconstruct(self):
#         name, path, args, kwargs = super(S3FileField, self).deconstruct()
# 
#         if self.upload_to != '':
#             kwargs['upload_to'] = self.upload_to
# 
#         if self.storage != default_storage:
#             kwargs['storage'] = self.storage
# 
#         if kwargs.get('max_length') == 200:
#             del kwargs['max_length']
# 
#         return name, path, args, kwargs
# 
#     def from_db_value(self, value, expression, connection, context):
#         return S3File(value, self, original_url=value)
# 
#     def to_python(self, value):
#         if value is None or isinstance(value, S3File):
#             return value
#         return S3File(value, self)
# 
#     def get_prep_value(self, value):
#         if isinstance(value, S3File):
#             return value.url
# 
#         return value
# 
#     def pre_save(self, model_instance, add):
#         file = getattr(model_instance, self.name)
#         file.save()
#         if not add and file.original_url and file.original_url != file.url:
#             key = key_from_url(file.original_url, self.upload_to)
#             self.storage.delete(key)
# 
#         return file.url
# 
#     def formfield(self, *args, **kwargs):
#         widget = S3FileUploadWidget(upload_to=self.upload_to,
#                                     accepted_types=self.accepted_types)
#         defaults = {'widget': widget}
#         defaults.update(kwargs)
#         return super(S3FileField, self).formfield(**defaults)


from django.db import models
from buckets.fields import S3FileField

TYPES = ['image/jpeg', 'application/gpx+xml', 'text/plain']


class FileModel(models.Model):
    name = models.CharField(max_length=200)
    file = S3FileField(upload_to='test', accepted_types=TYPES,

# Path: buckets/fields.py
# class S3FileField(models.Field):
#     """ Stores and provides access to a file stored in an AWS S3 bucket. To set
#         the value of an `S3FileField` you usually provide the URL of the file
#         in the bucket. Internally this URL is converted to a `S3File`, which
#         provides access to the actual file on S3."""
#     attr_class = S3File
#     descriptor_class = S3FileDescriptor
# 
#     description = _("A file stored in an AWS S3 buckets.")
# 
#     def __init__(self, upload_to='', storage=None, accepted_types=None,
#                  *args, **kwargs):
#         self.storage = storage or default_storage
#         self.upload_to = upload_to
#         self.accepted_types = accepted_types
# 
#         kwargs['max_length'] = kwargs.get('max_length', 200)
#         super(S3FileField, self).__init__(*args, **kwargs)
# 
#     def get_internal_type(self):
#         return 'CharField'
# 
#     def contribute_to_class(self, cls, name, **kwargs):
#         super(S3FileField, self).contribute_to_class(cls, name, **kwargs)
#         setattr(cls, self.name, self.descriptor_class(self))
# 
#     def deconstruct(self):
#         name, path, args, kwargs = super(S3FileField, self).deconstruct()
# 
#         if self.upload_to != '':
#             kwargs['upload_to'] = self.upload_to
# 
#         if self.storage != default_storage:
#             kwargs['storage'] = self.storage
# 
#         if kwargs.get('max_length') == 200:
#             del kwargs['max_length']
# 
#         return name, path, args, kwargs
# 
#     def from_db_value(self, value, expression, connection, context):
#         return S3File(value, self, original_url=value)
# 
#     def to_python(self, value):
#         if value is None or isinstance(value, S3File):
#             return value
#         return S3File(value, self)
# 
#     def get_prep_value(self, value):
#         if isinstance(value, S3File):
#             return value.url
# 
#         return value
# 
#     def pre_save(self, model_instance, add):
#         file = getattr(model_instance, self.name)
#         file.save()
#         if not add and file.original_url and file.original_url != file.url:
#             key = key_from_url(file.original_url, self.upload_to)
#             self.storage.delete(key)
# 
#         return file.url
# 
#     def formfield(self, *args, **kwargs):
#         widget = S3FileUploadWidget(upload_to=self.upload_to,
#                                     accepted_types=self.accepted_types)
#         defaults = {'widget': widget}
#         defaults.update(kwargs)
#         return super(S3FileField, self).formfield(**defaults)


# Path: example/exampleapp/models.py
from django.db import models
from buckets.fields import S3FileField


TYPES = ['image/jpeg', 'application/gpx+xml', 'text/plain']


class FileModel(models.Model):
    name = models.CharField(max_length=200)
    file = S3FileField(upload_to='test', accepted_types=TYPES,

                       null=True, blank=True)