예제 #1
0
def init_document_options(document):
    if not isinstance(document._meta,
                      (DocumentMetaWrapper, LazyDocumentMetaWrapper)):
        document._meta = DocumentMetaWrapper(document)
    # Workaround for Django 1.7+
    document._deferred = False
    # FIXME: Wrong implementation for Relations (https://github.com/django/django/blob/master/django/db/models/base.py#L601)
    document.serializable_value = lambda self, field_name: self._meta.get_field(
        field_name)
    return document
예제 #2
0
def label_for_field(name, model, model_admin=None, return_attr=False):
    attr = None
    model._admin_opts = DocumentMetaWrapper(model)
    try:
        field = model._admin_opts.get_field_by_name(name)[0]
        label = field.name.replace('_', ' ')
    except FieldDoesNotExist: 
        if name == "__unicode__":
            label = force_unicode(model._admin_opts.verbose_name)
        elif name == "__str__":
            label = smart_str(model._admin_opts.verbose_name)
        else:
            if callable(name):
                attr = name
            elif model_admin is not None and hasattr(model_admin, name):
                attr = getattr(model_admin, name)
            elif hasattr(model, name):
                attr = getattr(model, name)
            else:
                message = "Unable to lookup '%s' on %s" % (name, model._meta.object_name)
                if model_admin:
                    message += " or %s" % (model_admin.__class__.__name__,)
                raise AttributeError(message)


            if hasattr(attr, "short_description"):
                label = attr.short_description
            elif callable(attr):
                if attr.__name__ == "<lambda>":
                    label = "--"
                else:
                    label = pretty_name(attr.__name__)
            else:
                label = pretty_name(name)
    if return_attr:
        return (label, attr)
    else:
        return label
    def __init__(self, options=None):
        # document class can be declared with 'document =' or 'model ='
        self.document = getattr(options, 'document', None)
        if self.document is None:
            self.document = getattr(options, 'model', None)

        self.model = self.document
        meta = getattr(self.document, '_meta', {})
        # set up the document meta wrapper if document meta is a dict
        if self.document is not None and \
                not isinstance(meta, DocumentMetaWrapper):
            self.document._meta = DocumentMetaWrapper(self.document)
        self.fields = getattr(options, 'fields', None)
        self.exclude = getattr(options, 'exclude', None)
        self.widgets = getattr(options, 'widgets', None)
        self.embedded_field = getattr(options, 'embedded_field_name', None)
        self.formfield_generator = getattr(options, 'formfield_generator',
                                           _fieldgenerator)

        self._dont_save = []

        self.labels = getattr(options, 'labels', None)
        self.help_texts = getattr(options, 'help_texts', None)
예제 #4
0
def validate_base(cls, model):
    opts = model._meta
    if isinstance(opts, dict):
        opts = DocumentMetaWrapper(model)

    # raw_id_fields
    if hasattr(cls, 'raw_id_fields'):
        check_isseq(cls, 'raw_id_fields', cls.raw_id_fields)
        for idx, field in enumerate(cls.raw_id_fields):
            f = get_field(cls, model, opts, 'raw_id_fields', field)
            if not (isinstance(f, ReferenceField) or \
                    (isinstance(f, ListField) and isinstance(f.field, ReferenceField))):
                raise ImproperlyConfigured(
                    "'%s.raw_id_fields[%d]', '%s' must "
                    "be either a ReferenceField or a ListField(ReferenceField())."
                    % (cls.__name__, idx, field))

    # fields
    if cls.fields:  # default value is None
        check_isseq(cls, 'fields', cls.fields)
        for field in cls.fields:
            if field in cls.readonly_fields:
                # Stuff can be put in fields that isn't actually a model field
                # if it's in readonly_fields, readonly_fields will handle the
                # validation of such things.
                continue
            check_formfield(cls, model, opts, 'fields', field)
            try:
                f = opts.get_field(field)
            except models.FieldDoesNotExist:
                # If we can't find a field on the model that matches,
                # it could be an extra field on the form.
                continue
            if isinstance(f, models.ManyToManyField
                          ) and not f.rel.through._meta.auto_created:
                raise ImproperlyConfigured(
                    "'%s.fields' can't include the ManyToManyField "
                    "field '%s' because '%s' manually specifies "
                    "a 'through' model." % (cls.__name__, field, field))
        if cls.fieldsets:
            raise ImproperlyConfigured(
                'Both fieldsets and fields are specified in %s.' %
                cls.__name__)
        if len(cls.fields) > len(set(cls.fields)):
            raise ImproperlyConfigured(
                'There are duplicate field(s) in %s.fields' % cls.__name__)

    # fieldsets
    if cls.fieldsets:  # default value is None
        check_isseq(cls, 'fieldsets', cls.fieldsets)
        for idx, fieldset in enumerate(cls.fieldsets):
            check_isseq(cls, 'fieldsets[%d]' % idx, fieldset)
            if len(fieldset) != 2:
                raise ImproperlyConfigured("'%s.fieldsets[%d]' does not "
                                           "have exactly two elements." %
                                           (cls.__name__, idx))
            check_isdict(cls, 'fieldsets[%d][1]' % idx, fieldset[1])
            if 'fields' not in fieldset[1]:
                raise ImproperlyConfigured(
                    "'fields' key is required in "
                    "%s.fieldsets[%d][1] field options dict." %
                    (cls.__name__, idx))
            for fields in fieldset[1]['fields']:
                # The entry in fields might be a tuple. If it is a standalone
                # field, make it into a tuple to make processing easier.
                if type(fields) != tuple:
                    fields = (fields, )
                for field in fields:
                    if field in cls.readonly_fields:
                        # Stuff can be put in fields that isn't actually a
                        # model field if it's in readonly_fields,
                        # readonly_fields will handle the validation of such
                        # things.
                        continue
                    check_formfield(cls, model, opts,
                                    "fieldsets[%d][1]['fields']" % idx, field)
                    try:
                        f = opts.get_field(field)
                        if isinstance(
                                f, models.ManyToManyField
                        ) and not f.rel.through._meta.auto_created:
                            raise ImproperlyConfigured(
                                "'%s.fieldsets[%d][1]['fields']' "
                                "can't include the ManyToManyField field '%s' because "
                                "'%s' manually specifies a 'through' model." %
                                (cls.__name__, idx, field, field))
                    except models.FieldDoesNotExist:
                        # If we can't find a field on the model that matches,
                        # it could be an extra field on the form.
                        pass
        flattened_fieldsets = flatten_fieldsets(cls.fieldsets)
        if len(flattened_fieldsets) > len(set(flattened_fieldsets)):
            raise ImproperlyConfigured(
                'There are duplicate field(s) in %s.fieldsets' % cls.__name__)

    # exclude
    if cls.exclude:  # default value is None
        check_isseq(cls, 'exclude', cls.exclude)
        for field in cls.exclude:
            check_formfield(cls, model, opts, 'exclude', field)
            try:
                f = opts.get_field(field)
            except models.FieldDoesNotExist:
                # If we can't find a field on the model that matches,
                # it could be an extra field on the form.
                continue
        if len(cls.exclude) > len(set(cls.exclude)):
            raise ImproperlyConfigured(
                'There are duplicate field(s) in %s.exclude' % cls.__name__)

    # form
    # TODO: FInd out why issubclass doesn't work!
    if hasattr(cls, 'form') and not (issubclass(cls.form, BaseModelForm)
                                     or cls.form.__class__.__name__
                                     == 'DocumentFormMetaclass'):
        raise ImproperlyConfigured("%s.form does not inherit from "
                                   "BaseModelForm." % cls.__name__)

    # filter_vertical
    if hasattr(cls, 'filter_vertical'):
        check_isseq(cls, 'filter_vertical', cls.filter_vertical)
        for idx, field in enumerate(cls.filter_vertical):
            f = get_field(cls, model, opts, 'filter_vertical', field)
            if not isinstance(f, models.ManyToManyField):
                raise ImproperlyConfigured("'%s.filter_vertical[%d]' must be "
                                           "a ManyToManyField." %
                                           (cls.__name__, idx))

    # filter_horizontal
    if hasattr(cls, 'filter_horizontal'):
        check_isseq(cls, 'filter_horizontal', cls.filter_horizontal)
        for idx, field in enumerate(cls.filter_horizontal):
            f = get_field(cls, model, opts, 'filter_horizontal', field)
            if not isinstance(f, ListField) and not isinstance(
                    f.field, ReferenceField):
                raise ImproperlyConfigured(
                    "'%s.filter_horizontal[%d]' must be "
                    "a ManyToManyField." % (cls.__name__, idx))

    # radio_fields
    if hasattr(cls, 'radio_fields'):
        check_isdict(cls, 'radio_fields', cls.radio_fields)
        for field, val in list(cls.radio_fields.items()):
            f = get_field(cls, model, opts, 'radio_fields', field)
            if not (isinstance(f, models.ForeignKey) or f.choices):
                raise ImproperlyConfigured(
                    "'%s.radio_fields['%s']' "
                    "is neither an instance of ForeignKey nor does "
                    "have choices set." % (cls.__name__, field))
            if not val in (HORIZONTAL, VERTICAL):
                raise ImproperlyConfigured(
                    "'%s.radio_fields['%s']' "
                    "is neither admin.HORIZONTAL nor admin.VERTICAL." %
                    (cls.__name__, field))

    # prepopulated_fields
    if hasattr(cls, 'prepopulated_fields'):
        check_isdict(cls, 'prepopulated_fields', cls.prepopulated_fields)
        for field, val in list(cls.prepopulated_fields.items()):
            f = get_field(cls, model, opts, 'prepopulated_fields', field)
            if isinstance(f, (models.DateTimeField, models.ForeignKey,
                              models.ManyToManyField)):
                raise ImproperlyConfigured(
                    "'%s.prepopulated_fields['%s']' "
                    "is either a DateTimeField, ForeignKey or "
                    "ManyToManyField. This isn't allowed." %
                    (cls.__name__, field))
            check_isseq(cls, "prepopulated_fields['%s']" % field, val)
            for idx, f in enumerate(val):
                get_field(cls, model, opts,
                          "prepopulated_fields['%s'][%d]" % (field, idx), f)
예제 #5
0
def get_document_options(document):
    return DocumentMetaWrapper(document)
예제 #6
0
def validate_base(cls, model):
    opts = model._meta
    if isinstance(opts, dict):
        opts = DocumentMetaWrapper(model)

    # raw_id_fields
    if hasattr(cls, 'raw_id_fields'):
        check_isseq(cls, 'raw_id_fields', cls.raw_id_fields)
        for idx, field in enumerate(cls.raw_id_fields):
            f = get_field(cls, model, opts, 'raw_id_fields', field)
            if not isinstance(f, (models.ForeignKey, models.ManyToManyField)):
                raise ImproperlyConfigured("'%s.raw_id_fields[%d]', '%s' must "
                        "be either a ForeignKey or ManyToManyField."
                        % (cls.__name__, idx, field))

    # fields
    if cls.fields: # default value is None
        check_isseq(cls, 'fields', cls.fields)
        for field in cls.fields:
            if field in cls.readonly_fields:
                # Stuff can be put in fields that isn't actually a model field
                # if it's in readonly_fields, readonly_fields will handle the
                # validation of such things.
                continue
            check_formfield(cls, model, opts, 'fields', field)
            try:
                f = opts.get_field(field)
            except models.FieldDoesNotExist:
                # If we can't find a field on the model that matches,
                # it could be an extra field on the form.
                continue
            if isinstance(f, models.ManyToManyField) and not f.rel.through._meta.auto_created:
                raise ImproperlyConfigured("'%s.fields' can't include the ManyToManyField "
                    "field '%s' because '%s' manually specifies "
                    "a 'through' model." % (cls.__name__, field, field))
        if cls.fieldsets:
            raise ImproperlyConfigured('Both fieldsets and fields are specified in %s.' % cls.__name__)
        if len(cls.fields) > len(set(cls.fields)):
            raise ImproperlyConfigured('There are duplicate field(s) in %s.fields' % cls.__name__)

    # fieldsets
    if cls.fieldsets: # default value is None
        check_isseq(cls, 'fieldsets', cls.fieldsets)
        for idx, fieldset in enumerate(cls.fieldsets):
            check_isseq(cls, 'fieldsets[%d]' % idx, fieldset)
            if len(fieldset) != 2:
                raise ImproperlyConfigured("'%s.fieldsets[%d]' does not "
                        "have exactly two elements." % (cls.__name__, idx))
            check_isdict(cls, 'fieldsets[%d][1]' % idx, fieldset[1])
            if 'fields' not in fieldset[1]:
                raise ImproperlyConfigured("'fields' key is required in "
                        "%s.fieldsets[%d][1] field options dict."
                        % (cls.__name__, idx))
            for fields in fieldset[1]['fields']:
                # The entry in fields might be a tuple. If it is a standalone
                # field, make it into a tuple to make processing easier.
                if type(fields) != tuple:
                    fields = (fields,)
                for field in fields:
                    if field in cls.readonly_fields:
                        # Stuff can be put in fields that isn't actually a
                        # model field if it's in readonly_fields,
                        # readonly_fields will handle the validation of such
                        # things.
                        continue
                    check_formfield(cls, model, opts, "fieldsets[%d][1]['fields']" % idx, field)
                    try:
                        f = opts.get_field(field)
                        if isinstance(f, models.ManyToManyField) and not f.rel.through._meta.auto_created:
                            raise ImproperlyConfigured("'%s.fieldsets[%d][1]['fields']' "
                                "can't include the ManyToManyField field '%s' because "
                                "'%s' manually specifies a 'through' model." % (
                                    cls.__name__, idx, field, field))
                    except models.FieldDoesNotExist:
                        # If we can't find a field on the model that matches,
                        # it could be an extra field on the form.
                        pass
        flattened_fieldsets = flatten_fieldsets(cls.fieldsets)
        if len(flattened_fieldsets) > len(set(flattened_fieldsets)):
            raise ImproperlyConfigured('There are duplicate field(s) in %s.fieldsets' % cls.__name__)

    # exclude
    if cls.exclude: # default value is None
        check_isseq(cls, 'exclude', cls.exclude)
        for field in cls.exclude:
            check_formfield(cls, model, opts, 'exclude', field)
            try:
                f = opts.get_field(field)
            except models.FieldDoesNotExist:
                # If we can't find a field on the model that matches,
                # it could be an extra field on the form.
                continue
        if len(cls.exclude) > len(set(cls.exclude)):
            raise ImproperlyConfigured('There are duplicate field(s) in %s.exclude' % cls.__name__)

    # form
    # TODO: FInd out why issubclass doesn't work!
    if hasattr(cls, 'form') and not (issubclass(cls.form, BaseModelForm) or 
                                     cls.form.__class__.__name__ == 'DocumentFormMetaclass'):
        raise ImproperlyConfigured("%s.form does not inherit from "
                "BaseModelForm." % cls.__name__)

    # filter_vertical
    if hasattr(cls, 'filter_vertical'):
        check_isseq(cls, 'filter_vertical', cls.filter_vertical)
        for idx, field in enumerate(cls.filter_vertical):
            f = get_field(cls, model, opts, 'filter_vertical', field)
            if not isinstance(f, models.ManyToManyField):
                raise ImproperlyConfigured("'%s.filter_vertical[%d]' must be "
                    "a ManyToManyField." % (cls.__name__, idx))

    # filter_horizontal
    if hasattr(cls, 'filter_horizontal'):
        check_isseq(cls, 'filter_horizontal', cls.filter_horizontal)
        for idx, field in enumerate(cls.filter_horizontal):
            f = get_field(cls, model, opts, 'filter_horizontal', field)
            if not isinstance(f, ListField) and not isinstance(f.field, ReferenceField):
                raise ImproperlyConfigured("'%s.filter_horizontal[%d]' must be "
                    "a ManyToManyField." % (cls.__name__, idx))

    # radio_fields
    if hasattr(cls, 'radio_fields'):
        check_isdict(cls, 'radio_fields', cls.radio_fields)
        for field, val in cls.radio_fields.items():
            f = get_field(cls, model, opts, 'radio_fields', field)
            if not (isinstance(f, models.ForeignKey) or f.choices):
                raise ImproperlyConfigured("'%s.radio_fields['%s']' "
                        "is neither an instance of ForeignKey nor does "
                        "have choices set." % (cls.__name__, field))
            if not val in (HORIZONTAL, VERTICAL):
                raise ImproperlyConfigured("'%s.radio_fields['%s']' "
                        "is neither admin.HORIZONTAL nor admin.VERTICAL."
                        % (cls.__name__, field))

    # prepopulated_fields
    if hasattr(cls, 'prepopulated_fields'):
        check_isdict(cls, 'prepopulated_fields', cls.prepopulated_fields)
        for field, val in cls.prepopulated_fields.items():
            f = get_field(cls, model, opts, 'prepopulated_fields', field)
            if isinstance(f, (models.DateTimeField, models.ForeignKey,
                models.ManyToManyField)):
                raise ImproperlyConfigured("'%s.prepopulated_fields['%s']' "
                        "is either a DateTimeField, ForeignKey or "
                        "ManyToManyField. This isn't allowed."
                        % (cls.__name__, field))
            check_isseq(cls, "prepopulated_fields['%s']" % field, val)
            for idx, f in enumerate(val):
                get_field(cls, model, opts, "prepopulated_fields['%s'][%d]" % (field, idx), f)
예제 #7
0
def init_document_options(document):
    if not isinstance(document._meta, (DocumentMetaWrapper, LazyDocumentMetaWrapper)):
        document._meta = DocumentMetaWrapper(document)
    return document