Esempio n. 1
0
def get_verbose_name(model_or_queryset, field_path):
    if isinstance(model_or_queryset, Manager):
        model = model_or_queryset.model
    elif isinstance(model_or_queryset, QuerySet):
        model = model_or_queryset.model
    elif isinstance(model_or_queryset, Model):
        model = model_or_queryset
    else:
        raise AttributeError("`get_verbose_name` expects Manager, Queryset or Model as first parameter")

    if isinstance(field_path, basestring):
        field = get_field_by_path(model, field_path)
    elif isinstance(field_path, models.Field):
        field = field_path

    return field.verbose_name
Esempio n. 2
0
def merge(master, other, fields=None, commit=False, m2m=None, related=None):  # noqa
    """
        Merge 'other' into master.

        `fields` is a list of fieldnames that must be readed from ``other`` to put into master.
        If ``fields`` is None ``master`` will get all the ``other`` values except primary_key.
        Finally ``other`` will be deleted and master will be preserved

    @param master:  Model instance
    @param other: Model instance
    @param fields: list of fieldnames to  merge
    @param m2m: list of m2m fields to merge. If empty will be removed
    @param related: list of related fieldnames to merge. If empty will be removed
    @return:
    """

    fields = fields or [f.name for f in master._meta.fields]

    all_m2m = {}
    all_related = {}

    if related == ALL_FIELDS:
        related = [rel.get_accessor_name()
                   for rel in compat.get_all_related_objects(master)]
# for rel in master._meta.get_all_related_objects(False, False, False)]

    if m2m == ALL_FIELDS:
        m2m = [field.name for field in master._meta.many_to_many]

    if m2m and not commit:
        raise ValueError('Cannot save related with `commit=False`')
    with compat.atomic():
        result = clone_instance(master)

        for fieldname in fields:
            f = get_field_by_path(master, fieldname)
            if f and not f.primary_key:
                setattr(result, fieldname, getattr(other, fieldname))

        if m2m:
            for fieldname in set(m2m):
                all_m2m[fieldname] = []
                field_object = get_field_by_path(master, fieldname)
                if not isinstance(field_object, ManyToManyField):
                    raise ValueError('{0} is not a ManyToManyField field'.format(fieldname))
                source_m2m = getattr(other, field_object.name)
                for r in source_m2m.all():
                    all_m2m[fieldname].append(r)
        if related:
            for name in set(related):
                related_object = get_field_by_path(master, name)
                all_related[name] = []
                if related_object and isinstance(related_object.field, OneToOneField):
                    try:
                        accessor = getattr(other, name)
                        all_related[name] = [(related_object.field.name, accessor)]
                    except ObjectDoesNotExist:
                        pass
                else:
                    accessor = getattr(other, name, None)
                    if accessor:
                        rel_fieldname = list(accessor.core_filters.keys())[0].split('__')[0]
                        for r in accessor.all():
                            all_related[name].append((rel_fieldname, r))

        if commit:
            for name, elements in list(all_related.items()):
                for rel_fieldname, element in elements:
                    setattr(element, rel_fieldname, master)
                    element.save()

            other.delete()
            result.save()
            for fieldname, elements in list(all_m2m.items()):
                dest_m2m = getattr(result, fieldname)
                for element in elements:
                    dest_m2m.add(element)
    return result