Ejemplo n.º 1
0
def organisation_directory(request):
    """REST view for the update directory."""

    page = request.rsr_page
    all_organisations = Organisation.objects.all() if not page else _page_organisations(page)

    # Filter updates based on query parameters
    filter_, text_filter = _create_filters_query(request)
    organisations = (
        all_organisations.filter(filter_).distinct() if filter_ is not None else all_organisations
    )
    organisations_text_filtered = (
        organisations.filter(text_filter) if text_filter is not None else organisations
    )
    if organisations_text_filtered.exists():
        organisations = organisations_text_filtered

    # Get the relevant data for typeaheads based on filtered organisations (minus
    # text filtering, if no organisations were found)
    locations = [
        {'id': choice[0], 'name': choice[1]}
        for choice in location_choices(organisations)
    ]

    display_organisations = get_qs_elements_for_page(organisations_text_filtered, request)

    # Get related objects of page at once
    response = {
        'project_count': organisations_text_filtered.count(),
        'projects': OrganisationDirectorySerializer(display_organisations, many=True).data,
        'location': locations,
    }
    return Response(response)
Ejemplo n.º 2
0
def organisation_directory(request):
    """REST view for the update directory."""

    page = request.rsr_page
    all_organisations = Organisation.objects.all() if not page else page.partners()

    # Filter updates based on query parameters
    filter_, text_filter = _create_filters_query(request)
    organisations = (
        all_organisations.filter(filter_).distinct() if filter_ is not None else all_organisations
    )
    organisations_text_filtered = (
        organisations.filter(text_filter) if text_filter is not None else organisations
    )
    if organisations_text_filtered.exists():
        organisations = organisations_text_filtered

    # Get the relevant data for typeaheads based on filtered organisations (minus
    # text filtering, if no organisations were found)
    locations = [
        {'id': choice[0], 'name': choice[1]}
        for choice in location_choices(organisations)
    ]

    count = organisations_text_filtered.count()
    display_organisations = get_qs_elements_for_page(organisations_text_filtered, request, count)

    # Get related objects of page at once
    response = {
        'project_count': organisations_text_filtered.count(),
        'projects': OrganisationDirectorySerializer(display_organisations, many=True).data,
        'location': locations,
        'page_size_default': settings.PROJECT_DIRECTORY_PAGE_SIZES[0],
    }
    return Response(response)
Ejemplo n.º 3
0
def update_directory(request):
    """REST view for the update directory."""

    # Fetch updates based on whether we are on Akvo site or RSR main site
    page = request.rsr_page
    all_updates = _all_updates() if not page else page.updates()

    # Filter updates based on query parameters
    filter_, text_filter = _create_filters_query(request)
    updates = all_updates.filter(
        filter_).distinct() if filter_ is not None else all_updates

    updates_text_filtered = updates.filter(
        text_filter) if text_filter is not None else updates
    if updates_text_filtered.exists():
        updates = updates_text_filtered

    # Get the relevant data for typeaheads based on filtered updates (minus
    # text filtering, if no updates were found)
    locations = [{
        'id': choice[0],
        'name': choice[1]
    } for choice in location_choices(updates)]
    project_ids = updates.values_list('project__id', flat=True)
    projects = Project.objects.filter(id__in=project_ids)
    organisations = projects.all_partners().values('id', 'name', 'long_name')

    # FIXME: Currently only vocabulary 2 is supported (as was the case with
    # static filters). This could be extended to other vocabularies, in future.
    valid_sectors = dict(codelist_choices(SECTOR_CATEGORY))
    sectors = projects.sectors().filter(
        vocabulary='2',
        sector_code__in=valid_sectors).values('sector_code').distinct()

    count = updates_text_filtered.count()
    display_updates = get_qs_elements_for_page(updates_text_filtered, request,
                                               count)
    display_updates = display_updates.select_related(
        'project',
        'project__primary_location',
        'project__primary_organisation',
        'user',
    ).prefetch_related('project__partners', 'project__sectors', 'locations',
                       'locations__country')

    response = {
        'project_count': count,
        'projects': ProjectUpdateDirectorySerializer(display_updates,
                                                     many=True).data,
        'organisation': TypeaheadOrganisationSerializer(organisations,
                                                        many=True).data,
        'location': locations,
        'sector': TypeaheadSectorSerializer(sectors, many=True).data,
        'page_size_default': settings.PROJECT_DIRECTORY_PAGE_SIZES[0],
    }
    return Response(response)
Ejemplo n.º 4
0
def update_directory(request):
    """REST view for the update directory."""

    # Fetch updates based on whether we are on Akvo site or RSR main site
    page = request.rsr_page
    all_updates = _all_updates() if not page else _page_updates(page)

    # Filter updates based on query parameters
    filter_, text_filter = _create_filters_query(request)
    updates = all_updates.filter(filter_).distinct() if filter_ is not None else all_updates

    updates_text_filtered = updates.filter(text_filter) if text_filter is not None else updates
    if updates_text_filtered.exists():
        updates = updates_text_filtered

    # Get the relevant data for typeaheads based on filtered updates (minus
    # text filtering, if no updates were found)
    locations = [
        {'id': choice[0], 'name': choice[1]}
        for choice in location_choices(updates)
    ]
    project_ids = updates.values_list('project__id', flat=True)
    projects = Project.objects.filter(id__in=project_ids)
    organisations = projects.all_partners().values('id', 'name', 'long_name')

    # FIXME: Currently only vocabulary 2 is supported (as was the case with
    # static filters). This could be extended to other vocabularies, in future.
    valid_sectors = dict(codelist_choices(SECTOR_CATEGORY))
    sectors = projects.sectors().filter(
        vocabulary='2', sector_code__in=valid_sectors
    ).values('sector_code').distinct()

    display_updates = get_qs_elements_for_page(updates_text_filtered, request)
    count = updates_text_filtered.count()
    display_updates = display_updates.select_related(
        'project',
        'project__primary_location',
        'project__primary_organisation',
        'user',
    ).prefetch_related(
        'project__partners',
        'project__sectors',
        'locations',
        'locations__country'
    )

    response = {
        'project_count': count,
        'projects': ProjectUpdateDirectorySerializer(display_updates, many=True).data,
        'organisation': TypeaheadOrganisationSerializer(organisations, many=True).data,
        'location': locations,
        'sector': TypeaheadSectorSerializer(sectors, many=True).data,
        'page_size_default': settings.PROJECT_DIRECTORY_PAGE_SIZES[0],
    }
    return Response(response)
Ejemplo n.º 5
0
def directory(request):
    """The Organisation list view."""
    qs = remove_empty_querydict_items(request.GET)

    # Set show_filters to "in" if any filter is selected
    filter_class = show_filter_class(qs, [
        'location',
    ])

    # Yank Organisation collection
    all_organisations = _organisation_directory_coll(request)

    # Easter egg feature
    creator_organisations = request.GET.get('creator', False)
    if creator_organisations:
        all_organisations = all_organisations.filter(can_create_projects=True)

    f = OrganisationFilter(qs, queryset=all_organisations)

    # Change filter options further when on an Akvo Page
    if request.rsr_page:
        # Filter location filter list to only populated locations
        f.filters['location'].extra['choices'] = location_choices(
            all_organisations)

    # Build page
    page = request.GET.get('page')
    page, paginator, page_range = pagination(page, f.qs.distinct(), 10)

    # Get organisations to be displayed on the map
    if request.rsr_page and request.rsr_page.all_maps:
        map_orgs = all_organisations
    else:
        map_orgs = page.object_list
    map_orgs = map_orgs

    # Get related objects of page at once
    page.object_list = page.object_list.prefetch_related('locations')

    return render(
        request, 'organisation_directory.html', {
            'orgs_count': f.qs.distinct().count(),
            'filter': f,
            'page': page,
            'paginator': paginator,
            'page_range': page_range,
            'show_filters': filter_class,
            'q': filter_query_string(qs),
            'map_organisations': map_orgs,
        })
Ejemplo n.º 6
0
def directory(request):
    """The Organisation list view."""
    qs = remove_empty_querydict_items(request.GET)

    # Set show_filters to "in" if any filter is selected
    filter_class = show_filter_class(qs, ['location', ])

    # Yank Organisation collection
    all_organisations = _organisation_directory_coll(request)

    # Easter egg feature
    creator_organisations = request.GET.get('creator', False)
    if creator_organisations:
        all_organisations = all_organisations.filter(can_create_projects=True)

    f = OrganisationFilter(qs, queryset=all_organisations)

    # Change filter options further when on an Akvo Page
    if request.rsr_page:
        # Filter location filter list to only populated locations
        f.filters['location'].extra['choices'] = location_choices(all_organisations)

    # Build page
    page = request.GET.get('page')
    page, paginator, page_range = pagination(page, f.qs.distinct(), 10)

    # Get organisations to be displayed on the map
    if request.rsr_page and request.rsr_page.all_maps:
        map_orgs = all_organisations
    else:
        map_orgs = page.object_list
    map_orgs = map_orgs

    # Get related objects of page at once
    page.object_list = page.object_list.prefetch_related('locations')

    return render(request, 'organisation_directory.html', {
        'orgs_count': f.qs.distinct().count(),
        'filter': f,
        'page': page,
        'paginator': paginator,
        'page_range': page_range,
        'show_filters': filter_class,
        'q': filter_query_string(qs),
        'map_organisations': map_orgs,
    })
Ejemplo n.º 7
0
def project_directory(request):
    """Return the values for various project filters.

    Based on the current filters, it returns new options for all the (other)
    filters. This is used to generate dynamic filters.

    """

    # Fetch projects based on whether we are an Akvo site or RSR main site
    page = request.rsr_page
    projects = page.projects() if page else Project.objects.all().public().published()

    # Exclude projects which don't have an image or a title
    # FIXME: This happens silently and may be confusing?
    projects = projects.exclude(Q(title='') | Q(current_image=''))

    # Filter projects based on query parameters
    filter_, text_filter = _create_filters_query(request)
    projects = projects.filter(filter_).distinct() if filter_ is not None else projects
    # NOTE: The text filter is handled differently/separately from the other filters.
    # The text filter allows users to enter free form text, which could result in no
    # projects being found for the given text. Other fields only allow selecting from
    # a list of options, and for every combination that is shown to users and
    # selectable by them, at least one project exists.
    # When no projects are returned for a given search string, if the text search is
    # not handled separately, the options for all the other filters are empty, and
    # this causes the filters to get cleared automatically. This is very weird UX.
    projects_text_filtered = (
        projects.filter(text_filter) if text_filter is not None else projects
    )
    if projects_text_filtered.exists():
        projects = projects_text_filtered

    # Pre-fetch related fields to make things faster
    projects = projects.select_related(
        'primary_location',
        'primary_organisation',
    ).prefetch_related(
        'locations',
        'locations__country',
        'recipient_countries',
        'recipient_countries__country',
    )

    # Get the relevant data for typeaheads based on filtered projects (minus
    # text filtering, if no projects were found)
    cached_locations, _ = get_cached_data(request, 'locations', None, None)
    if cached_locations is None:
        cached_locations = [
            {'id': choice[0], 'name': choice[1]}
            for choice in location_choices(projects)
        ]
        set_cached_data(request, 'locations', cached_locations)

    organisations = projects.all_partners().values('id', 'name', 'long_name')

    # FIXME: Currently only vocabulary 2 is supported (as was the case with
    # static filters). This could be extended to other vocabularies, in future.
    valid_sectors = dict(codelist_choices(SECTOR_CATEGORY))
    sectors = projects.sectors().filter(
        vocabulary='2', sector_code__in=valid_sectors
    ).values('sector_code').distinct()

    # NOTE: We use projects_text_filtered for displaying projects
    count = projects_text_filtered.count()
    display_projects = get_qs_elements_for_page(projects_text_filtered, request).select_related(
        'primary_organisation'
    )

    # NOTE: We use the _get_cached_data function to individually cache small
    # bits of data to avoid the response from never getting saved in the cache,
    # because the response is larger than the max size of data that can be
    # saved in the cache.
    cached_projects, showing_cached_projects = get_cached_data(
        request, 'projects', display_projects, ProjectDirectorySerializer
    )
    cached_organisations, _ = get_cached_data(
        request, 'organisations', organisations, TypeaheadOrganisationSerializer
    )

    response = {
        'project_count': count,
        'projects': cached_projects,
        'showing_cached_projects': showing_cached_projects,
        'organisation': cached_organisations,
        'sector': TypeaheadSectorSerializer(sectors, many=True).data,
        'location': cached_locations,
        'page_size_default': settings.PROJECT_DIRECTORY_PAGE_SIZES[0],
    }

    return Response(response)
Ejemplo n.º 8
0
def project_directory(request):
    """Return the values for various project filters.

    Based on the current filters, it returns new options for all the (other)
    filters. This is used to generate dynamic filters.

    """

    # Fetch projects based on whether we are an Akvo site or RSR main site
    page = request.rsr_page
    projects = page.projects() if page else Project.objects.all().public(
    ).published()

    # Exclude projects which don't have an image or a title
    # FIXME: This happens silently and may be confusing?
    projects = projects.exclude(Q(title='') | Q(current_image=''))

    # Filter projects based on query parameters
    filter_, text_filter = _create_filters_query(request)
    projects = projects.filter(
        filter_).distinct() if filter_ is not None else projects
    # NOTE: The text filter is handled differently/separately from the other filters.
    # The text filter allows users to enter free form text, which could result in no
    # projects being found for the given text. Other fields only allow selecting from
    # a list of options, and for every combination that is shown to users and
    # selectable by them, at least one project exists.
    # When no projects are returned for a given search string, if the text search is
    # not handled separately, the options for all the other filters are empty, and
    # this causes the filters to get cleared automatically. This is very weird UX.
    projects_text_filtered = (projects.filter(text_filter)
                              if text_filter is not None else projects)
    if projects_text_filtered.exists():
        projects = projects_text_filtered

    # Pre-fetch related fields to make things faster
    projects = projects.select_related(
        'primary_location',
        'primary_organisation',
    ).prefetch_related(
        'locations',
        'locations__country',
        'recipient_countries',
        'recipient_countries__country',
    )

    # Get the relevant data for typeaheads based on filtered projects (minus
    # text filtering, if no projects were found)
    cached_locations, _ = get_cached_data(request, 'locations', None, None)
    if cached_locations is None:
        cached_locations = [{
            'id': choice[0],
            'name': choice[1]
        } for choice in location_choices(projects)]
        set_cached_data(request, 'locations', cached_locations)

    organisations = projects.all_partners().values('id', 'name', 'long_name')

    # FIXME: Currently only vocabulary 2 is supported (as was the case with
    # static filters). This could be extended to other vocabularies, in future.
    valid_sectors = dict(codelist_choices(SECTOR_CATEGORY))
    sectors = projects.sectors().filter(
        vocabulary='2',
        sector_code__in=valid_sectors).values('sector_code').distinct()

    # NOTE: We use projects_text_filtered for displaying projects
    count = projects_text_filtered.count()
    display_projects = get_qs_elements_for_page(
        projects_text_filtered, request).select_related('primary_organisation')

    # NOTE: We use the _get_cached_data function to individually cache small
    # bits of data to avoid the response from never getting saved in the cache,
    # because the response is larger than the max size of data that can be
    # saved in the cache.
    cached_projects, showing_cached_projects = get_cached_data(
        request, 'projects', display_projects, ProjectDirectorySerializer)
    cached_organisations, _ = get_cached_data(request, 'organisations',
                                              organisations,
                                              TypeaheadOrganisationSerializer)

    response = {
        'project_count': count,
        'projects': cached_projects,
        'showing_cached_projects': showing_cached_projects,
        'organisation': cached_organisations,
        'sector': TypeaheadSectorSerializer(sectors, many=True).data,
        'location': cached_locations,
        'page_size_default': settings.PROJECT_DIRECTORY_PAGE_SIZES[0],
    }

    return Response(response)