コード例 #1
0
ファイル: views.py プロジェクト: knabar/fynbos
def record(request, id, name, contexttype=None, contextid=None, contextname=None,
           edit=False, customize=False, personal=False, copy=False,
           copyid=None, copyname=None):

    collections = apply_collection_visibility_preferences(request.user, Collection.objects.all())
    writable_collections = list(filter_by_access(request.user, collections, write=True).values_list('id', flat=True))
    readable_collections = list(filter_by_access(request.user, collections).values_list('id', flat=True))
    personal_collections = None
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)
        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated():
            if personal:
                personal_collections = get_allowed_collections_for_personal_records(request.user, readable_collections)
            if writable_collections or (personal and personal_collections):
                record = Record()
                if personal:
                    record.owner = request.user
            else:
                raise Http404()
        else:
            raise Http404()

    if record.owner:
        if personal_collections is None:
            personal_collections = get_allowed_collections_for_personal_records(request.user, readable_collections)
        valid_collections = set(personal_collections) | set(writable_collections)
    else:
        valid_collections = writable_collections

    context = None
    if contexttype and contextid:
        app_label, model = contexttype.split('.')
        model_class = get_object_or_404(ContentType, app_label=app_label, model=model).model_class()
        context = get_object_or_404(filter_by_access(request.user, model_class), id=contextid)

    media = Media.objects.select_related().filter(record=record,
                                                  storage__in=filter_by_access(request.user, Storage))

    # Can any media be downloaded?
    download_image = False

    # Only list media that is downloadable or editable
    for m in media:
        # Calculate permissions and store with object for later use in template
        m.downloadable_in_template =  m.is_downloadable_by(request.user)
        m.editable_in_template = m.editable_by(request.user)
        download_image = download_image or m.is_downloadable_by(request.user, original=False)

    media = filter(lambda m: m.downloadable_in_template or m.editable_in_template, media)

    edit = edit and request.user.is_authenticated()

    copyrecord = Record.get_or_404(copyid, request.user) if copyid else None

    class FieldSetForm(forms.Form):
        fieldset = FieldSetChoiceField(user=request.user, default_label='Default' if not edit else None)

    fieldsetform = FieldSetForm(request.GET)
    if fieldsetform.is_valid():
        fieldset = FieldSet.for_user(request.user).get(id=fieldsetform.cleaned_data['fieldset']) if fieldsetform.cleaned_data['fieldset'] else None
    elif id and name:
        fieldset = None
    else:
        # Creating new record, use DC fieldset by default
        fieldset = FieldSet.objects.get(name='dc')

    collection_items = collectionformset = None

    if edit:

        if not can_edit and not customize and not context:
            return HttpResponseRedirect(reverse('data-record', kwargs=dict(id=id, name=name)))

        def _field_choices():
            fsf = list(FieldSetField.objects.select_related('fieldset', 'field').all().order_by('fieldset__name', 'order', 'field__label'))
            grouped = {}
            for f in fsf:
                grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field)
            others = list(Field.objects.exclude(id__in=[f.field.id for f in fsf]).order_by('label').values_list('id', 'label'))
            choices = [('', '-' * 10)] + [(set[0], [(f.id, f.label) for f in fields])
                for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0])]
            if others:
                choices.append(('Others', others))
            return choices

        class FieldValueForm(forms.ModelForm):

            def __init__(self, *args, **kwargs):
                super(FieldValueForm, self).__init__(*args, **kwargs)

            def clean_field(self):
                return Field.objects.get(id=self.cleaned_data['field'])

            def clean_context_type(self):
                context = self.cleaned_data.get('context_type')
                if context:
                    context = ContentType.objects.get(id=context)
                return context

            def clean(self):
                cleaned_data = self.cleaned_data
                return cleaned_data

            field = forms.ChoiceField(choices=_field_choices())
            value = forms.CharField(widget=forms.Textarea, required=False)
            context_type = forms.IntegerField(widget=forms.HiddenInput, required=False)
            context_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
            index_value = forms.CharField(widget=forms.HiddenInput, required=False)

            class Meta:
                model = FieldValue
                exclude = []


        class CollectionForm(forms.Form):

            id = forms.IntegerField(widget=forms.HiddenInput)
            title = forms.CharField(widget=DisplayOnlyTextWidget)
            member = forms.BooleanField(required=False)
            shared = forms.BooleanField(required=False)


        fieldvalues_readonly = []
        if customize or context:
            fieldvalues = record.get_fieldvalues(owner=request.user, context=context, hidden=True).filter(owner=request.user)
        else:
            fieldvalues = record.get_fieldvalues(hidden=True)

        FieldValueFormSet = modelformset_factory(FieldValue, form=FieldValueForm,
                                                 exclude=FieldValueForm.Meta.exclude, can_delete=True, extra=3)

        CollectionFormSet = formset_factory(CollectionForm, extra=0)


        if request.method == 'POST':
            formset = FieldValueFormSet(request.POST, request.FILES, queryset=fieldvalues, prefix='fv')
            collectionformset = CollectionFormSet(request.POST, request.FILES, prefix='c') if not (customize or context) else None
            if formset.is_valid() and (customize or context or collectionformset.is_valid()):# or metadataform.is_valid()):

                record.save()

                if not (customize or context):
                    collections = dict((c['id'],c)
                        for c in collectionformset.cleaned_data
                        if c['id'] in valid_collections)
                    for item in record.collectionitem_set.filter(collection__in=valid_collections):
                        if collections.has_key(item.collection_id):
                            if not collections[item.collection_id]['member']:
                                item.delete()
                            elif collections[item.collection_id]['shared'] == item.hidden:
                                item.hidden = not item.hidden
                                item.save()
                            del collections[item.collection_id]
                    for coll in collections.values():
                        if coll['member']:
                            CollectionItem.objects.create(record=record,
                                                          collection_id=coll['id'],
                                                          hidden=not coll['shared'])

                instances = formset.save(commit=False)
                o1 = fieldvalues and max(v.order for v in fieldvalues) or 0
                o2 = instances and max(v.order for v in instances) or 0
                order = max(o1, o2, 0)
                for instance in instances:
                    if not instance.value:
                        if instance.id:
                            instance.delete()
                        continue
                    instance.record = record
                    if instance.order == 0:
                        order += 1
                        instance.order = order
                    if customize or context:
                        instance.owner = request.user
                    if context:
                        instance.context = context
                    instance.save()
                request.user.message_set.create(message="Record saved successfully.")

                url = reverse('data-record-edit-customize' if customize else 'data-record-edit',
                              kwargs=dict(id=record.id, name=record.name))

                next = request.GET.get('next',
                       reverse('data-record', kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(url if request.POST.has_key('save_and_continue') else next)
        else:

            if copyrecord:
                initial = []
                for fv in copyrecord.get_fieldvalues(hidden=True):
                    initial.append(dict(
                        label=fv.label,
                        field=fv.field_id,
                        refinement=fv.refinement,
                        value=fv.value,
                        date_start=fv.date_start,
                        date_end=fv.date_end,
                        numeric_value=fv.numeric_value,
                        language=fv.language,
                        order=fv.order,
                        group=fv.group,
                        hidden=fv.hidden,
                    ))
                FieldValueFormSet.extra = len(initial) + 3
            elif fieldset:
                needed = fieldset.fields.filter(~Q(id__in=[fv.field_id for fv in fieldvalues])).order_by('fieldsetfield__order').values_list('id', flat=True)
                initial = [{}] * len(fieldvalues) + [{'field': id} for id in needed]
                FieldValueFormSet.extra = len(needed) + 3
            else:
                initial = []

            formset = FieldValueFormSet(queryset=fieldvalues, prefix='fv', initial=initial)
            if not (customize or context):

                collections = dict(
                    ((coll.id, dict(id=coll.id, title=coll.title))
                        for coll in Collection.objects.filter(id__in=valid_collections)
                    )
                )

                for item in (copyrecord or record).collectionitem_set.all():
                    collections.get(item.collection_id, {}).update(dict(
                        member=True,
                        shared=not item.hidden,
                    ))

                collections = sorted(collections.values(), key=lambda c: c['title'])

                collectionformset = CollectionFormSet(prefix='c', initial=collections)

    else:
        fieldvalues_readonly = record.get_fieldvalues(owner=request.user, fieldset=fieldset)
        formset = None
        q = Q() if record.owner == request.user or request.user.is_superuser else Q(hidden=False)
        collection_items = record.collectionitem_set.filter(q, collection__in=readable_collections)

    if can_edit:
        from rooibos.storage.views import media_upload_form
        UploadFileForm = media_upload_form(request)
        upload_form = UploadFileForm() if UploadFileForm else None
    else:
        upload_form = None

    record_usage = record.presentationitem_set.values('presentation') \
                    .distinct().count() if can_edit else 0

    back_url = HistoryMiddleware.go_back(
        request,
        to_before=reverse('data-record-back-helper-url'),
    )

    return render_to_response('data_record.html',
                              {'record': record,
                               'media': media,
                               'fieldsetform': fieldsetform,
                               'fieldset': fieldset,
                               'fieldvalues': fieldvalues_readonly,
                               'context': context,
                               'customize': customize,
                               'fv_formset': formset,
                               'c_formset': collectionformset,
                               'can_edit': can_edit,
                               'can_manage': can_manage,
                               'next': request.GET.get('next'),
                               'collection_items': collection_items,
                               'upload_form': upload_form,
                               'upload_url': ("%s?sidebar&next=%s" % (reverse('storage-media-upload', args=(record.id, record.name)), request.get_full_path()))
                                             if record.id else None,
                               'record_usage': record_usage,
                               'back_url': back_url,
                               'download_image': download_image,
                               },
                              context_instance=RequestContext(request))
コード例 #2
0
ファイル: views.py プロジェクト: hanleybrand/rooibos
def record(request,
           id,
           name,
           contexttype=None,
           contextid=None,
           contextname=None,
           edit=False,
           customize=False,
           personal=False,
           copy=False,
           copyid=None,
           copyname=None):

    collections = apply_collection_visibility_preferences(
        request.user, Collection.objects.all())
    writable_collections = list(
        filter_by_access(request.user, collections,
                         write=True).values_list('id', flat=True))
    readable_collections = list(
        filter_by_access(request.user, collections).values_list('id',
                                                                flat=True))
    personal_collections = None
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)
        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated():
            if personal:
                personal_collections = \
                    get_allowed_collections_for_personal_records(
                        request.user, readable_collections)
            if writable_collections or (personal and personal_collections):
                record = Record()
                if personal:
                    record.owner = request.user
            else:
                raise Http404()
        else:
            raise Http404()

    if record.owner:
        if personal_collections is None:
            personal_collections = \
                get_allowed_collections_for_personal_records(
                    request.user, readable_collections)
        valid_collections = (set(personal_collections)
                             | set(writable_collections))
    else:
        valid_collections = writable_collections

    context = None
    if contexttype and contextid:
        app_label, model = contexttype.split('.')
        model_class = get_object_or_404(ContentType,
                                        app_label=app_label,
                                        model=model).model_class()
        context = get_object_or_404(filter_by_access(request.user,
                                                     model_class),
                                    id=contextid)

    media = Media.objects.select_related().filter(record=record,
                                                  storage__in=filter_by_access(
                                                      request.user, Storage))

    # Can any media be downloaded?
    download_image = False

    # Only list media that is downloadable or editable
    for m in media:
        # Calculate permissions and store with object for later use in template
        m.downloadable_in_template = m.is_downloadable_by(request.user)
        m.editable_in_template = m.editable_by(request.user)
        download_image = download_image or \
            m.is_downloadable_by(request.user, original=False)

    media = [
        m for m in media
        if m.downloadable_in_template or m.editable_in_template
    ]

    edit = edit and request.user.is_authenticated()

    copyrecord = Record.get_or_404(copyid, request.user) if copyid else None

    class FieldSetForm(forms.Form):
        fieldset = FieldSetChoiceField(
            user=request.user, default_label='Default' if not edit else None)

    fieldsetform = FieldSetForm(request.GET)
    if fieldsetform.is_valid():
        if fieldsetform.cleaned_data['fieldset']:
            fieldset = FieldSet.for_user(
                request.user).get(id=fieldsetform.cleaned_data['fieldset'])
        else:
            fieldset = None
    elif edit:
        default_fieldset_name = getattr(settings, 'RECORD_DEFAULT_FIELDSET',
                                        'dc')
        # Creating new record, use DC fieldset by default
        fieldset = FieldSet.objects.get(name=default_fieldset_name)
    else:
        fieldset = None

    collection_items = collectionformset = None

    if edit:

        if not can_edit and not customize and not context:
            return HttpResponseRedirect(
                reverse('data-record', kwargs=dict(id=id, name=name)))

        def _field_choices():
            fsf = list(
                FieldSetField.objects.select_related('fieldset',
                                                     'field').all().order_by(
                                                         'fieldset__name',
                                                         'order',
                                                         'field__label'))
            grouped = {}
            for f in fsf:
                grouped.setdefault((f.fieldset.title, f.fieldset.id),
                                   []).append(f.field)
            others = list(
                Field.objects.exclude(
                    id__in=[f.field.id
                            for f in fsf]).order_by('label').values_list(
                                'id', 'label'))
            choices = [('', '-' * 10)
                       ] + [(set[0], [(f.id, f.label) for f in fields])
                            for set, fields in sorted(iter(grouped.items()),
                                                      key=lambda s: s[0][0])]
            if others:
                choices.append(('Others', others))
            return choices

        class FieldValueForm(forms.ModelForm):
            def __init__(self, *args, **kwargs):
                super(FieldValueForm, self).__init__(*args, **kwargs)

            def clean_field(self):
                return Field.objects.get(id=self.cleaned_data['field'])

            def clean_context_type(self):
                context = self.cleaned_data.get('context_type')
                if context:
                    context = ContentType.objects.get(id=context)
                return context

            def clean(self):
                cleaned_data = self.cleaned_data
                return cleaned_data

            field = forms.ChoiceField(choices=_field_choices())
            value = forms.CharField(widget=forms.Textarea, required=False)
            context_type = forms.IntegerField(widget=forms.HiddenInput,
                                              required=False)
            context_id = forms.IntegerField(widget=forms.HiddenInput,
                                            required=False)
            index_value = forms.CharField(widget=forms.HiddenInput,
                                          required=False)
            browse_value = forms.CharField(widget=forms.HiddenInput,
                                           required=False)

            class Meta:
                model = FieldValue
                fields = "__all__"

        class CollectionForm(forms.Form):
            id = forms.IntegerField(widget=forms.HiddenInput)
            title = forms.CharField(widget=DisplayOnlyTextWidget)
            member = forms.BooleanField(required=False)
            shared = forms.BooleanField(required=False)

        fieldvalues_readonly = []
        if customize or context:
            fieldvalues = record.get_fieldvalues(
                owner=request.user, context=context,
                hidden=True).filter(owner=request.user)
        else:
            fieldvalues = record.get_fieldvalues(hidden=True)

        field_value_formset = modelformset_factory(
            FieldValue,
            form=FieldValueForm,
            fields=FieldValueForm.Meta.fields,
            can_delete=True,
            extra=3)

        collection_formset = formset_factory(CollectionForm, extra=0)

        if request.method == 'POST':
            formset = field_value_formset(request.POST,
                                          request.FILES,
                                          queryset=fieldvalues,
                                          prefix='fv')
            if not (customize or context):
                collectionformset = collection_formset(request.POST,
                                                       request.FILES,
                                                       prefix='c')
            else:
                collectionformset = None
            if formset.is_valid() and (customize or context
                                       or collectionformset.is_valid()):

                record.save()

                if not (customize or context):
                    collections = dict((c['id'], c)
                                       for c in collectionformset.cleaned_data
                                       if c['id'] in valid_collections)
                    for item in record.collectionitem_set.filter(
                            collection__in=valid_collections):
                        if item.collection_id in collections:
                            if not collections[item.collection_id]['member']:
                                item.delete()
                            elif collections[item.collection_id]['shared'] == \
                                    item.hidden:
                                item.hidden = not item.hidden
                                item.save()
                            del collections[item.collection_id]
                    for coll in list(collections.values()):
                        if coll['member']:
                            CollectionItem.objects.create(
                                record=record,
                                collection_id=coll['id'],
                                hidden=not coll['shared'])

                instances = formset.save(commit=False)
                # Explicitly remove deleted objects
                for instance in formset.deleted_objects:
                    instance.delete()
                o1 = fieldvalues and max(v.order or 0
                                         for v in fieldvalues) or 0
                o2 = instances and max(v.order or 0 for v in instances) or 0
                order = max(o1, o2, 0)
                for instance in instances:
                    if not instance.value:
                        if instance.id:
                            instance.delete()
                        continue
                    instance.record = record
                    if instance.order == 0:
                        order += 1
                        instance.order = order
                    if customize or context:
                        instance.owner = request.user
                    if context:
                        instance.context = context
                    instance.save()

                messages.add_message(request,
                                     messages.INFO,
                                     message="Record saved successfully.")

                url = reverse('data-record-edit-customize'
                              if customize else 'data-record-edit',
                              kwargs=dict(id=record.id, name=record.name))

                next = validate_next_link(
                    request.GET.get('next'),
                    reverse('data-record',
                            kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(url if 'save_and_continue' in
                                            request.POST else next)
        else:

            if copyrecord:
                initial = []
                for fv in copyrecord.get_fieldvalues(hidden=True):
                    initial.append(
                        dict(
                            label=fv.label,
                            field=fv.field_id,
                            refinement=fv.refinement,
                            value=fv.value,
                            date_start=fv.date_start,
                            date_end=fv.date_end,
                            numeric_value=fv.numeric_value,
                            language=fv.language,
                            order=fv.order,
                            group=fv.group,
                            hidden=fv.hidden,
                        ))
                field_value_formset.extra = len(initial) + 3
            elif fieldset:
                needed = fieldset.fields.filter(~Q(
                    id__in=[fv.field_id for fv in fieldvalues])).order_by(
                        'fieldsetfield__order').values_list('id', flat=True)
                initial = [{'field': id2} for id2 in needed]
                field_value_formset.extra = len(needed) + 3
            else:
                initial = []

            formset = field_value_formset(queryset=fieldvalues,
                                          prefix='fv',
                                          initial=initial)
            if not (customize or context):

                collections = dict(((coll.id, dict(id=coll.id,
                                                   title=coll.title))
                                    for coll in Collection.objects.filter(
                                        id__in=valid_collections)))

                for item in (copyrecord or record).collectionitem_set.all():
                    collections.get(item.collection_id, {}).update(
                        dict(
                            member=True,
                            shared=not item.hidden,
                        ))

                collections = list(collections.values())

                collectionformset = collection_formset(prefix='c',
                                                       initial=collections)

        part_of_works = None
        related_works = None

    else:
        fieldvalues_readonly = record.get_fieldvalues(owner=request.user,
                                                      fieldset=fieldset)
        formset = None
        if record.owner == request.user or request.user.is_superuser:
            q = Q()
        else:
            q = Q(hidden=False)
        collection_items = record.collectionitem_set.filter(
            q, collection__in=readable_collections)

        part_of_works = []
        related_works = []

        works = FieldValue.objects.filter(
            record=record,
            field__name='relation',
            field__standard__prefix='dc',
            owner=None,
        ).values_list('value', 'refinement')

        for work, refinement in works:
            if refinement and refinement.lower() == 'ispartof':
                part_of_works.append(work)
            elif not refinement:
                related_works.append(work)

    if can_edit:
        from rooibos.storage.views import media_upload_form
        upload_file_form = media_upload_form(request)
        upload_form = upload_file_form() if upload_file_form else None
    else:
        upload_form = None

    record_usage = record.presentationitem_set.values('presentation') \
        .distinct().count() if can_edit else 0

    back_url = HistoryMiddleware.go_back(
        request,
        to_before=reverse('data-record-back-helper-url'),
    )

    if record.id:
        upload_url = (
            "%s?sidebar&next=%s" %
            (reverse('storage-media-upload', args=(record.id, record.name)),
             request.get_full_path() + '?refreshthumb=1'))
    else:
        upload_url = None

    # In edit mode, optionally hide fieldset dropdown
    if formset and getattr(settings, 'HIDE_RECORD_FIELDSETS', False):
        fieldsetform = None

    return render(
        request, 'data_record.html', {
            'record': record,
            'media': media,
            'fieldsetform': fieldsetform,
            'fieldset': fieldset,
            'fieldvalues': fieldvalues_readonly,
            'context': context,
            'customize': customize,
            'fv_formset': formset,
            'c_formset': collectionformset,
            'can_edit': can_edit,
            'can_manage': can_manage,
            'next': validate_next_link(request.GET.get('next')),
            'collection_items': collection_items,
            'upload_form': upload_form,
            'upload_url': upload_url,
            'record_usage': record_usage,
            'back_url': back_url,
            'download_image': download_image,
            'part_of_works': part_of_works,
            'related_works': related_works,
        })
コード例 #3
0
ファイル: views.py プロジェクト: gitter-badger/rooibos
def record(request,
           id,
           name,
           contexttype=None,
           contextid=None,
           contextname=None,
           edit=False,
           customize=False,
           personal=False,
           copy=False,
           copyid=None,
           copyname=None):

    collections = apply_collection_visibility_preferences(
        request.user, Collection.objects.all())
    writable_collections = list(
        filter_by_access(request.user, collections,
                         write=True).values_list('id', flat=True))
    readable_collections = list(
        filter_by_access(request.user, collections).values_list('id',
                                                                flat=True))
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)
        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated() and (writable_collections or
                                                (personal
                                                 and readable_collections)):
            record = Record()
            if personal:
                record.owner = request.user
        else:
            raise Http404()

    if record.owner:
        valid_collections = set(readable_collections) | set(
            writable_collections)
    else:
        valid_collections = writable_collections

    context = None
    if contexttype and contextid:
        app_label, model = contexttype.split('.')
        model_class = get_object_or_404(ContentType,
                                        app_label=app_label,
                                        model=model).model_class()
        context = get_object_or_404(filter_by_access(request.user,
                                                     model_class),
                                    id=contextid)

    media = Media.objects.select_related().filter(record=record,
                                                  storage__in=filter_by_access(
                                                      request.user, Storage))
    # Only list media that is downloadable or editable
    for m in media:
        # Calculate permissions and store with object for later use in template
        m.downloadable_in_template = m.is_downloadable_by(request.user)
        m.editable_in_template = m.editable_by(request.user)
    media = filter(
        lambda m: m.downloadable_in_template or m.editable_in_template, media)

    edit = edit and request.user.is_authenticated()

    copyrecord = Record.get_or_404(copyid, request.user) if copyid else None

    class FieldSetForm(forms.Form):
        fieldset = FieldSetChoiceField(
            user=request.user, default_label='Default' if not edit else None)

    fieldsetform = FieldSetForm(request.GET)
    if fieldsetform.is_valid():
        fieldset = FieldSet.for_user(request.user).get(
            id=fieldsetform.cleaned_data['fieldset']
        ) if fieldsetform.cleaned_data['fieldset'] else None
    elif id and name:
        fieldset = None
    else:
        # Creating new record, use DC fieldset by default
        fieldset = FieldSet.objects.get(name='dc')

    collection_items = collectionformset = None

    if edit:

        if not can_edit and not customize and not context:
            return HttpResponseRedirect(
                reverse('data-record', kwargs=dict(id=id, name=name)))

        def _field_choices():
            fsf = list(
                FieldSetField.objects.select_related('fieldset',
                                                     'field').all().order_by(
                                                         'fieldset__name',
                                                         'order',
                                                         'field__label'))
            grouped = {}
            for f in fsf:
                grouped.setdefault((f.fieldset.title, f.fieldset.id),
                                   []).append(f.field)
            others = list(
                Field.objects.exclude(
                    id__in=[f.field.id
                            for f in fsf]).order_by('label').values_list(
                                'id', 'label'))
            choices = [('', '-' * 10)
                       ] + [(set[0], [(f.id, f.label) for f in fields])
                            for set, fields in sorted(grouped.iteritems(),
                                                      key=lambda s: s[0][0])]
            if others:
                choices.append(('Others', others))
            return choices

        class FieldValueForm(forms.ModelForm):
            def __init__(self, *args, **kwargs):
                super(FieldValueForm, self).__init__(*args, **kwargs)

            def clean_field(self):
                return Field.objects.get(id=self.cleaned_data['field'])

            def clean_context_type(self):
                context = self.cleaned_data.get('context_type')
                if context:
                    context = ContentType.objects.get(id=context)
                return context

            def clean(self):
                cleaned_data = self.cleaned_data
                return cleaned_data

            field = forms.ChoiceField(choices=_field_choices())
            value = forms.CharField(widget=forms.Textarea, required=False)
            context_type = forms.IntegerField(widget=forms.HiddenInput,
                                              required=False)
            context_id = forms.IntegerField(widget=forms.HiddenInput,
                                            required=False)
            index_value = forms.CharField(widget=forms.HiddenInput,
                                          required=False)

            class Meta:
                model = FieldValue
                exclude = []

        class CollectionForm(forms.Form):

            id = forms.IntegerField(widget=forms.HiddenInput)
            title = forms.CharField(widget=DisplayOnlyTextWidget)
            member = forms.BooleanField(required=False)
            shared = forms.BooleanField(required=False)

        fieldvalues_readonly = []
        if customize or context:
            fieldvalues = record.get_fieldvalues(
                owner=request.user, context=context,
                hidden=True).filter(owner=request.user)
        else:
            fieldvalues = record.get_fieldvalues(hidden=True)

        FieldValueFormSet = modelformset_factory(
            FieldValue,
            form=FieldValueForm,
            exclude=FieldValueForm.Meta.exclude,
            can_delete=True,
            extra=3)

        CollectionFormSet = formset_factory(CollectionForm, extra=0)

        if request.method == 'POST':
            formset = FieldValueFormSet(request.POST,
                                        request.FILES,
                                        queryset=fieldvalues,
                                        prefix='fv')
            collectionformset = CollectionFormSet(
                request.POST, request.FILES,
                prefix='c') if not (customize or context) else None
            if formset.is_valid() and (customize or context
                                       or collectionformset.is_valid()
                                       ):  # or metadataform.is_valid()):

                record.save()

                if not (customize or context):
                    collections = dict((c['id'], c)
                                       for c in collectionformset.cleaned_data
                                       if c['id'] in valid_collections)
                    for item in record.collectionitem_set.filter(
                            collection__in=valid_collections):
                        if collections.has_key(item.collection_id):
                            if not collections[item.collection_id]['member']:
                                item.delete()
                            elif collections[item.collection_id][
                                    'shared'] == item.hidden:
                                item.hidden = not item.hidden
                                item.save()
                            del collections[item.collection_id]
                    for coll in collections.values():
                        if coll['member']:
                            CollectionItem.objects.create(
                                record=record,
                                collection_id=coll['id'],
                                hidden=not coll['shared'])

                instances = formset.save(commit=False)
                o1 = fieldvalues and max(v.order for v in fieldvalues) or 0
                o2 = instances and max(v.order for v in instances) or 0
                order = max(o1, o2, 0)
                for instance in instances:
                    if not instance.value:
                        if instance.id:
                            instance.delete()
                        continue
                    instance.record = record
                    if instance.order == 0:
                        order += 1
                        instance.order = order
                    if customize or context:
                        instance.owner = request.user
                    if context:
                        instance.context = context
                    instance.save()
                request.user.message_set.create(
                    message="Record saved successfully.")

                url = reverse('data-record-edit-customize'
                              if customize else 'data-record-edit',
                              kwargs=dict(id=record.id, name=record.name))

                next = request.GET.get(
                    'next',
                    reverse('data-record',
                            kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(
                    url if request.POST.has_key('save_and_continue') else next)
        else:

            if copyrecord:
                initial = []
                for fv in copyrecord.get_fieldvalues(hidden=True):
                    initial.append(
                        dict(
                            label=fv.label,
                            field=fv.field_id,
                            refinement=fv.refinement,
                            value=fv.value,
                            date_start=fv.date_start,
                            date_end=fv.date_end,
                            numeric_value=fv.numeric_value,
                            language=fv.language,
                            order=fv.order,
                            group=fv.group,
                            hidden=fv.hidden,
                        ))
                FieldValueFormSet.extra = len(initial) + 3
            elif fieldset:
                needed = fieldset.fields.filter(~Q(
                    id__in=[fv.field_id for fv in fieldvalues])).order_by(
                        'fieldsetfield__order').values_list('id', flat=True)
                initial = [{}] * len(fieldvalues) + [{
                    'field': id
                } for id in needed]
                FieldValueFormSet.extra = len(needed) + 3
            else:
                initial = []

            formset = FieldValueFormSet(queryset=fieldvalues,
                                        prefix='fv',
                                        initial=initial)
            if not (customize or context):

                collections = dict(((coll.id, dict(id=coll.id,
                                                   title=coll.title))
                                    for coll in Collection.objects.filter(
                                        id__in=valid_collections)))

                for item in (copyrecord or record).collectionitem_set.all():
                    collections.get(item.collection_id, {}).update(
                        dict(
                            member=True,
                            shared=not item.hidden,
                        ))

                collections = sorted(collections.values(),
                                     key=lambda c: c['title'])

                collectionformset = CollectionFormSet(prefix='c',
                                                      initial=collections)

    else:
        fieldvalues_readonly = record.get_fieldvalues(owner=request.user,
                                                      fieldset=fieldset)
        formset = None
        q = Q(
        ) if record.owner == request.user or request.user.is_superuser else Q(
            hidden=False)
        collection_items = record.collectionitem_set.filter(
            q, collection__in=readable_collections)

    if can_edit:
        from rooibos.storage.views import media_upload_form
        UploadFileForm = media_upload_form(request)
        upload_form = UploadFileForm() if UploadFileForm else None
    else:
        upload_form = None

    record_usage = record.presentationitem_set.values('presentation') \
                    .distinct().count() if can_edit else 0

    return render_to_response('data_record.html', {
        'record':
        record,
        'media':
        media,
        'fieldsetform':
        fieldsetform,
        'fieldset':
        fieldset,
        'fieldvalues':
        fieldvalues_readonly,
        'context':
        context,
        'customize':
        customize,
        'fv_formset':
        formset,
        'c_formset':
        collectionformset,
        'can_edit':
        can_edit,
        'can_manage':
        can_manage,
        'next':
        request.GET.get('next'),
        'collection_items':
        collection_items,
        'upload_form':
        upload_form,
        'upload_url':
        ("%s?sidebar&next=%s" %
         (reverse('storage-media-upload', args=(record.id, record.name)),
          request.get_full_path())) if record.id else None,
        'record_usage':
        record_usage,
    },
                              context_instance=RequestContext(request))
コード例 #4
0
ファイル: views.py プロジェクト: thenoviceoof/rooibos
def record(
    request,
    id,
    name,
    contexttype=None,
    contextid=None,
    contextname=None,
    edit=False,
    customize=False,
    personal=False,
    copy=False,
    copyid=None,
    copyname=None,
):

    writable_collections = list(accessible_ids(request.user, Collection, write=True))
    readable_collections = list(accessible_ids(request.user, Collection))
    can_edit = request.user.is_authenticated()
    can_manage = False

    if id and name:
        record = Record.get_or_404(id, request.user)

        # if the user passes the first test
        if record:
            # if the user can't see an image, and there is one, then
            # don't let them see the record
            passwords = request.session.get("passwords", dict())
            media = get_media_for_record(record, request.user, passwords)
            unfiltered_media = Media.objects.filter(record__id=record.id)
            if not media and unfiltered_media:
                raise Http404()

        can_edit = can_edit and record.editable_by(request.user)
        can_manage = record.manageable_by(request.user)
    else:
        if request.user.is_authenticated() and (writable_collections or (personal and readable_collections)):
            record = Record()
            if personal:
                record.owner = request.user
        else:
            raise Http404()

    if record.owner:
        valid_collections = set(readable_collections) | set(writable_collections)
    else:
        valid_collections = writable_collections

    context = None
    if contexttype and contextid:
        app_label, model = contexttype.split(".")
        model_class = get_object_or_404(ContentType, app_label=app_label, model=model).model_class()
        context = get_object_or_404(filter_by_access(request.user, model_class), id=contextid)

    media = Media.objects.select_related().filter(record=record, storage__id__in=accessible_ids(request.user, Storage))
    # Only list media that is downloadable or editable
    for m in media:
        # Calculate permissions and store with object for later use in template
        m.downloadable_in_template = m.is_downloadable_by(request.user)
        m.editable_in_template = m.editable_by(request.user)
    media = filter(lambda m: m.downloadable_in_template or m.editable_in_template, media)

    edit = edit and request.user.is_authenticated()

    copyrecord = Record.get_or_404(copyid, request.user) if copyid else None

    class FieldSetForm(forms.Form):
        fieldset = FieldSetChoiceField(user=request.user, default_label="Default" if not edit else None)

    fieldsetform = FieldSetForm(request.GET)
    if fieldsetform.is_valid():
        fieldset = (
            FieldSet.for_user(request.user).get(id=fieldsetform.cleaned_data["fieldset"])
            if fieldsetform.cleaned_data["fieldset"]
            else None
        )
    elif (edit or customize) and (id and name):
        # if we're editing, touch all the data (no default fieldset)
        fieldset = None
    else:
        # use default fieldset settings
        if settings.DEFAULT_FIELDSET and isinstance(settings.DEFAULT_FIELDSET, basestring):
            default_fieldset = settings.DEFAULT_FIELDSET
        else:  # yes, it's a default default setting
            default_fieldset = "dc"
        fieldset = FieldSet.objects.get(name=default_fieldset)

    collection_items = collectionformset = None

    if edit:

        if not can_edit and not customize and not context:
            return HttpResponseRedirect(reverse("data-record", kwargs=dict(id=id, name=name)))

        def _field_choices():
            fsf = list(
                FieldSetField.objects.select_related("fieldset", "field")
                .all()
                .order_by("fieldset__name", "order", "field__label")
            )
            grouped = {}
            for f in fsf:
                grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field)
            others = list(
                Field.objects.exclude(id__in=[f.field.id for f in fsf]).order_by("label").values_list("id", "label")
            )
            choices = [("", "-" * 10)] + [
                (set[0], [(f.id, f.label) for f in fields])
                for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0])
            ]
            if others:
                choices.append(("Others", others))
            return choices

        class FieldValueForm(forms.ModelForm):
            def __init__(self, *args, **kwargs):
                super(FieldValueForm, self).__init__(*args, **kwargs)

            def clean_field(self):
                return Field.objects.get(id=self.cleaned_data["field"])

            def clean_context_type(self):
                context = self.cleaned_data.get("context_type")
                if context:
                    context = ContentType.objects.get(id=context)
                return context

            def clean(self):
                cleaned_data = self.cleaned_data
                return cleaned_data

            field = forms.ChoiceField(choices=_field_choices())
            value = forms.CharField(widget=forms.Textarea, required=False)
            context_type = forms.IntegerField(widget=forms.HiddenInput, required=False)
            context_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
            index_value = forms.CharField(widget=forms.HiddenInput, required=False)

            class Meta:
                model = FieldValue
                exclude = []

        class CollectionForm(forms.Form):

            id = forms.IntegerField(widget=forms.HiddenInput)
            title = forms.CharField(widget=DisplayOnlyTextWidget)
            member = forms.BooleanField(required=False)
            shared = forms.BooleanField(required=False)

        fieldvalues_readonly = []
        if customize or context:
            fieldvalues = record.get_fieldvalues(owner=request.user, context=context, hidden=True).filter(
                owner=request.user
            )
        else:
            fieldvalues = record.get_fieldvalues(hidden=True)

        FieldValueFormSet = modelformset_factory(
            FieldValue, form=FieldValueForm, exclude=FieldValueForm.Meta.exclude, can_delete=True, extra=3
        )

        CollectionFormSet = formset_factory(CollectionForm, extra=0)

        if request.method == "POST":
            formset = FieldValueFormSet(request.POST, request.FILES, queryset=fieldvalues, prefix="fv")
            collectionformset = (
                CollectionFormSet(request.POST, request.FILES, prefix="c") if not (customize or context) else None
            )
            if formset.is_valid() and (
                customize or context or collectionformset.is_valid()
            ):  # or metadataform.is_valid()):

                record.save()

                if not (customize or context):
                    collections = dict(
                        (c["id"], c) for c in collectionformset.cleaned_data if c["id"] in valid_collections
                    )
                    for item in record.collectionitem_set.filter(collection__in=valid_collections):
                        if collections.has_key(item.collection_id):
                            if not collections[item.collection_id]["member"]:
                                item.delete()
                            elif collections[item.collection_id]["shared"] == item.hidden:
                                item.hidden = not item.hidden
                                item.save()
                            del collections[item.collection_id]
                    for coll in collections.values():
                        if coll["member"]:
                            CollectionItem.objects.create(
                                record=record, collection_id=coll["id"], hidden=not coll["shared"]
                            )

                instances = formset.save(commit=False)
                o1 = fieldvalues and max(v.order for v in fieldvalues) or 0
                o2 = instances and max(v.order for v in instances) or 0
                order = max(o1, o2, 0)
                for instance in instances:
                    if not instance.value:
                        if instance.id:
                            instance.delete()
                        continue
                    instance.record = record
                    if instance.order == 0:
                        order += 1
                        instance.order = order
                    if customize or context:
                        instance.owner = request.user
                    if context:
                        instance.context = context
                    instance.save()
                request.user.message_set.create(message="Record saved successfully.")

                url = reverse(
                    "data-record-edit-customize" if customize else "data-record-edit",
                    kwargs=dict(id=record.id, name=record.name),
                )

                next = request.GET.get("next", reverse("data-record", kwargs=dict(id=record.id, name=record.name)))

                return HttpResponseRedirect(url if request.POST.has_key("save_and_continue") else next)
        else:

            if copyrecord:
                initial = []
                for fv in copyrecord.get_fieldvalues(hidden=True):
                    initial.append(
                        dict(
                            label=fv.label,
                            field=fv.field_id,
                            refinement=fv.refinement,
                            value=fv.value,
                            date_start=fv.date_start,
                            date_end=fv.date_end,
                            numeric_value=fv.numeric_value,
                            language=fv.language,
                            order=fv.order,
                            group=fv.group,
                            hidden=fv.hidden,
                        )
                    )
                FieldValueFormSet.extra = len(initial) + 3
            elif fieldset:
                needed = (
                    fieldset.fields.filter(~Q(id__in=[fv.field_id for fv in fieldvalues]))
                    .order_by("fieldsetfield__order")
                    .values_list("id", flat=True)
                )
                initial = [{}] * len(fieldvalues) + [{"field": id} for id in needed]
                FieldValueFormSet.extra = len(needed) + 3
            else:
                initial = []

            formset = FieldValueFormSet(queryset=fieldvalues, prefix="fv", initial=initial)
            if not (customize or context):

                collections = dict(
                    (
                        (coll.id, dict(id=coll.id, title=coll.title))
                        for coll in Collection.objects.filter(id__in=valid_collections)
                    )
                )

                for item in (copyrecord or record).collectionitem_set.all():
                    collections.get(item.collection_id, {}).update(dict(member=True, shared=not item.hidden))

                collections = sorted(collections.values(), key=lambda c: c["title"])

                collectionformset = CollectionFormSet(prefix="c", initial=collections)

    else:
        fieldvalues_readonly = record.get_fieldvalues(owner=request.user, fieldset=fieldset)
        formset = None
        q = Q() if record.owner == request.user or request.user.is_superuser else Q(hidden=False)
        collection_items = record.collectionitem_set.filter(q, collection__in=readable_collections)

    if can_edit:
        from rooibos.storage.views import media_upload_form

        UploadFileForm = media_upload_form(request)
        upload_form = UploadFileForm() if UploadFileForm else None
    else:
        upload_form = None

    # handle uploading over secure URLs: in the view, offer link to insecure
    insecure_url = None
    if request.is_secure() and settings.INSECURE_UPLOAD:
        request_url = request.build_absolute_uri(request.get_full_path())
        insecure_url = request_url.replace("https://", "http://")

    record_usage = record.presentationitem_set.values("presentation").distinct().count() if can_edit else 0

    return render_to_response(
        "data_record.html",
        {
            "record": record,
            "media": media,
            "fieldsetform": fieldsetform,
            "fieldset": fieldset,
            "fieldvalues": fieldvalues_readonly,
            "context": context,
            "customize": customize,
            "fv_formset": formset,
            "c_formset": collectionformset,
            "can_edit": can_edit,
            "can_manage": can_manage,
            "next": request.GET.get("next"),
            "collection_items": collection_items,
            "upload_form": upload_form,
            "upload_url": (
                "%s?sidebar&next=%s"
                % (reverse("storage-media-upload", args=(record.id, record.name)), request.get_full_path())
            )
            if record.id
            else None,
            "insecure_url": insecure_url,
            "record_usage": record_usage,
        },
        context_instance=RequestContext(request),
    )