Source code for accounts.views.search

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, get_object_or_404
from django.template.loader import render_to_string
from django.views.decorators.http import require_POST

from accounts.models import User, UnregisteredUser
from cobalt.settings import (
    RBAC_EVERYONE,
    TBA_PLAYER,
    GLOBAL_TITLE,
    GLOBAL_ORG,
    ABF_USER,
)
from masterpoints.views import search_mpc_users_by_name


[docs] @login_required() def member_search_ajax(request): """Ajax member search function. Used by the generic member search. Used to search for members by the Member to Member transfer part of Payments. Currently very specific to payments. Could be made more generic if other parts of the system need a search function. Args: lastname - partial lastname to search for. Wild cards the ending. firstname - partial firstname to search for. Wild cards the ending. search_id - used if page has multiple user searches. We just pass this through. Optional. Returns: HttpResponse - either a message or a list of users in HTML format. """ msg = "" if request.method == "GET": if "search_id" in request.GET: search_id = request.GET.get("search_id") else: search_id = None if "lastname" in request.GET: search_last_name = request.GET.get("lastname") else: search_last_name = None if "firstname" in request.GET: search_first_name = request.GET.get("firstname") else: search_first_name = None # flag to include the user in the output if "include_me" in request.GET: exclude_list = [RBAC_EVERYONE, TBA_PLAYER] else: exclude_list = [request.user.id, RBAC_EVERYONE, TBA_PLAYER] if search_first_name and search_last_name: members = User.objects.filter( first_name__istartswith=search_first_name, last_name__istartswith=search_last_name, ).exclude(pk__in=exclude_list) mpc_members = search_mpc_users_by_name(search_first_name, search_last_name) elif search_last_name: members = User.objects.filter( last_name__istartswith=search_last_name ).exclude(pk__in=exclude_list) mpc_members = search_mpc_users_by_name("", search_last_name) else: members = User.objects.filter( first_name__istartswith=search_first_name ).exclude(pk__in=exclude_list) mpc_members = search_mpc_users_by_name(search_first_name, "") homes = {int(mpc["ABFNumber"]): mpc["ClubName"] for mpc in mpc_members} # is_ajax has been removed from Django if request.headers.get("x-requested-with") == "XMLHttpRequest": if members.count() > 30: msg = "Too many results (%s)" % members.count() members = None elif members.count() == 0: msg = f"No matches found. Have they registered for {GLOBAL_TITLE}? Registration is free." html = render_to_string( template_name="accounts/search/search_results_ajax.html", context={ "members": members, "homes": homes, "msg": msg, "search_id": search_id, }, ) data_dict = {"data": html} return JsonResponse(data=data_dict, safe=False) return render( request, "accounts/search/search_results_ajax.html", context={"members": members, "msg": msg}, )
[docs] @login_required() def system_number_search_ajax(request): """Ajax system_number search function. Used by the generic member search. Args: system_number - exact number to search for Returns: HttpResponse - either a message or a list of users in HTML format. """ if request.method != "GET": return JsonResponse(data={"error": "Invalid request"}) exclude_list = [request.user.system_number, RBAC_EVERYONE, TBA_PLAYER] if "system_number" in request.GET: system_number = request.GET.get("system_number") member = User.objects.filter(system_number=system_number).first() else: system_number = None member = None if member and member.system_number not in exclude_list: status = "Success" msg = "Found member" member_id = member.id else: status = "Not Found" msg = f"No matches found for that {GLOBAL_ORG} number. Check they have registered for <strong>{GLOBAL_TITLE}</strong>. Registration is free." member_id = 0 data = {"member_id": member_id, "status": status, "msg": msg} data_dict = {"data": data} return JsonResponse(data=data_dict, safe=False)
[docs] @login_required() @require_POST def member_search_htmx(request): """Search on user first and last name. The goal of the member search is to finally replace the included search with a hidden user_id input field, the users name and a button to search again. Alternatively, a callback can be provided which will be called if/when a user is selected. All parameters are passed through in the request. search_id: optional identifier, required if there are multiple user searches on same page, must be unique but can be anything. Gets appended to any DOM objects that should be unique on the page. This is also used as the prefix for the final user_id field if user_id_field is not specified. user_id_field: Optional. At the end, if we find a matching user we will create an element for the user_id and an element for the user name to display. The user_id_field will be used as the name of the user_id input. If not specified then member{search_id} is used. include_me: Flag to include the logged in user in the search. Default is no. callback: Optional. If provided then this will be called when a member is picked. unregistered: Optional. If provided then we search for UnregisteredUsers instead of Users. """ # Get parameters search_id = request.POST.get("search_id", "") user_id_field = request.POST.get("user_id_field", "") callback = request.POST.get("callback", "") # Get partial first name to search for from form last_name_search = request.POST.get("last_name_search") first_name_search = request.POST.get("first_name_search") # If user enters data and then deletes it we can get nothing through - ignore if not last_name_search and not first_name_search: return HttpResponse("") # Get exclude list etc ( include_me, unregistered, base_queryset, exclude_list, ) = _get_exclude_list_and_base_values(request) if last_name_search and first_name_search: name_list = ( base_queryset.filter(last_name__istartswith=last_name_search) .filter(first_name__istartswith=first_name_search) .exclude(pk__in=exclude_list) ) # COB-469 - include home club where possible mpc_members = search_mpc_users_by_name(first_name_search, last_name_search) elif last_name_search: name_list = base_queryset.filter( last_name__istartswith=last_name_search ).exclude(pk__in=exclude_list) mpc_members = search_mpc_users_by_name("", last_name_search) else: name_list = base_queryset.filter( first_name__istartswith=first_name_search ).exclude(pk__in=exclude_list) mpc_members = search_mpc_users_by_name(first_name_search, "") homes = {int(mpc["ABFNumber"]): mpc["ClubName"] for mpc in mpc_members} # See if there is more data more_data = False if name_list.count() > 10: more_data = True name_list = name_list[:10] return render( request, "accounts/search/member_search_htmx.html", { "name_list": name_list, "homes": homes, "more_data": more_data, "search_id": search_id, "user_id_field": user_id_field, "include_me": include_me, "unregistered": unregistered, "callback": callback, }, )
[docs] @login_required() @require_POST def system_number_search_htmx(request): """Search on system number""" # Get parameters search_id = request.POST.get("search_id", "") callback = request.POST.get("callback", "") system_number = request.POST.get("system_number") if system_number == "": return HttpResponse( "" # "<span class='cobalt-form-error''>Enter a number to look up, or type in the name fields</span>" ) # Get exclude list etc ( include_me, unregistered, base_queryset, exclude_list, ) = _get_exclude_list_and_base_values(request) member = ( base_queryset.filter(system_number=system_number) .exclude(pk__in=exclude_list) .first() ) if member: return render( request, "accounts/search/name_match_htmx.html", { "member": member, "search_id": search_id, "user_id_field": system_number, "include_me": include_me, "callback": callback, }, ) else: return HttpResponse("No match found")
[docs] @login_required() @require_POST def member_match_htmx(request): """show member details when a user picks from the list of matches""" # Get parameters member_id = request.POST.get("member_id") search_id = request.POST.get("search_id", "") user_id_field = request.POST.get("user_id_field", "") callback = request.POST.get("callback", "") # Get exclude list etc ( include_me, unregistered, base_queryset, exclude_list, ) = _get_exclude_list_and_base_values(request) member = base_queryset.filter(pk=member_id).exclude(pk__in=exclude_list).first() if member: return render( request, "accounts/search/name_match_htmx.html", { "member": member, "search_id": search_id, "user_id_field": user_id_field, "include_me": include_me, "callback": callback, }, ) else: return HttpResponse("No match found")
[docs] @login_required() @require_POST def member_match_summary_htmx(request): """show outcome from search""" # Get parameters member_id = request.POST.get("member_id") search_id = request.POST.get("search_id", "") user_id_field = request.POST.get("user_id_field", "") include_me = bool(request.POST.get("include_me")) member = get_object_or_404(User, pk=member_id) return render( request, "accounts/search/name_match_summary_htmx.html", { "member": member, "search_id": search_id, "user_id_field": user_id_field, "include_me": include_me, }, )
[docs] @login_required() def member_detail_m2m_ajax(request): """Returns basic public info on a member. ONLY USED BY MEMBER TRANSFER. REPLACE. Ajax call to get basic info on a member. Will return an empty json array if the member number is invalid. Args: member_id - member number Returns: Json array: member, clubs, global org name. """ if request.method == "GET" and "member_id" in request.GET: member_id = request.GET.get("member_id") member = get_object_or_404(User, pk=member_id) # is_ajax has been removed from Django if request.headers.get("x-requested-with") == "XMLHttpRequest": global_org = settings.GLOBAL_ORG html = render_to_string( template_name="accounts/search/member_ajax.html", context={ "member": member, "global_org": global_org, }, ) data_dict = {"data": html} return JsonResponse(data=data_dict, safe=False) return JsonResponse(data={"error": "Invalid request"})
[docs] @login_required() def member_details_ajax(request): """Returns basic public info on a member for the generic member search. Ajax call to get basic info on a member. Will return an empty json array if the member number is invalid. Args: member_id - member number search_id - used if page has multiple user searches. We just pass this through. Optional. Returns: Json array: member, clubs, global org name. """ if request.method == "GET": if "search_id" in request.GET: search_id = request.GET.get("search_id") else: search_id = None if "member_id" in request.GET: member_id = request.GET.get("member_id") member = get_object_or_404(User, pk=member_id) # is_ajax has been removed from Django if request.headers.get("x-requested-with") == "XMLHttpRequest": global_org = settings.GLOBAL_ORG html = render_to_string( template_name="accounts/search/member_details_ajax.html", context={ "member": member, "global_org": global_org, "search_id": search_id, }, ) data_dict = { "data": html, "member": "%s" % member, "pic": f"{member.pic}", } return JsonResponse(data=data_dict, safe=False) return JsonResponse(data={"error": "Invalid request"})
[docs] @login_required() def search_ajax(request): """Ajax member search function. ONLY USED BY MEMBER TRANSFER. REPLACE. Used to search for members by the Member to Member transfer part of Payments. Currently very specific to payments. Could be made more generic if other parts of the system need a search function. Args: lastname - partial lastname to search for. Wild cards the ending. firstname - partial firstname to search for. Wild cards the ending. Returns: HttpResponse - either a message or a list of users in HTML format. """ msg = "" if request.method == "GET": if "lastname" in request.GET: search_last_name = request.GET.get("lastname") else: search_last_name = None if "firstname" in request.GET: search_first_name = request.GET.get("firstname") else: search_first_name = None if search_first_name and search_last_name: members = User.objects.filter( first_name__istartswith=search_first_name, last_name__istartswith=search_last_name, ).exclude(pk=request.user.id) elif search_last_name: members = User.objects.filter( last_name__istartswith=search_last_name ).exclude(pk=request.user.id) else: members = User.objects.filter( first_name__istartswith=search_first_name ).exclude(pk=request.user.id) # is_ajax has been removed from Django if request.headers.get("x-requested-with") == "XMLHttpRequest": if members.count() > 30: msg = "Too many results (%s)" % members.count() members = None elif members.count() == 0: msg = f"No matches found. Have they registered for {GLOBAL_TITLE}? Registration is free." html = render_to_string( template_name="accounts/search/search_results.html", context={"members": members, "msg": msg}, ) data_dict = {"data": html} return JsonResponse(data=data_dict, safe=False) return render( request, "accounts/search/search_results.html", context={"members": members, "msg": msg}, )
def _get_exclude_list_and_base_values(request): """get the 'exclude' list. System IDs and this user are excluded unless include_me is set""" # Check for include_me flag, otherwise don't include current user include_me = bool(request.POST.get("include_me")) # Check for unregistered, controls which user type we search User or UnregisteredUser unregistered = bool(request.POST.get("unregistered")) if unregistered: exclude_list = [] base_queryset = UnregisteredUser.objects.all() else: # ignore system accounts exclude_list = [RBAC_EVERYONE, TBA_PLAYER, ABF_USER] base_queryset = User.objects.all() # Ignore this user unless overridden if not include_me: exclude_list.append(request.user.id) return include_me, unregistered, base_queryset, exclude_list