import sys with open('core/views.py', 'r') as f: content = f.read() # Define the target function content exactly as we want it new_function = """@role_required(["admin", "campaign_manager", "campaign_staff", "system_admin", "campaign_admin"], permission="core.view_voter") def voter_advanced_search(request): """ Advanced search for voters with multiple filters. """ selected_tenant_id = request.session.get("tenant_id") if not selected_tenant_id: messages.warning(request, "Please select a campaign first.") return redirect("index") tenant = get_object_or_404(Tenant, id=selected_tenant_id) voters = Voter.objects.filter(tenant=tenant, is_inactive=False).order_by("last_name", "first_name") form = AdvancedVoterSearchForm(request.GET) if form.is_valid(): data = form.cleaned_data if data.get('first_name'): voters = voters.filter(first_name__icontains=data['first_name']) if data.get('last_name'): voters = voters.filter(last_name__icontains=data['last_name']) if data.get('address'): voters = voters.filter(Q(address__icontains=data['address']) | Q(address_street__icontains=data['address'])) if data.get('voter_id'): voters = voters.filter(voter_id__iexact=data['voter_id']) if data.get('birth_month'): voters = voters.filter(birthdate__month=data['birth_month']) if data.get('city'): voters = voters.filter(city__icontains=data['city']) if data.get('zip_code'): voters = voters.filter(zip_code__icontains=data['zip_code']) if data.get('neighborhood'): voters = voters.filter(neighborhood__icontains=data['neighborhood']) if data.get('district'): voters = voters.filter(district=data['district']) if data.get('precinct'): voters = voters.filter(precinct=data['precinct']) if data.get('email'): voters = voters.filter(email__icontains=data['email']) if data.get('phone'): voters = voters.filter(get_phone_search_filters(data['phone'])) if data.get('phone_type'): voters = voters.filter(phone_type=data['phone_type']) if data.get('is_targeted'): voters = voters.filter(is_targeted=(data['is_targeted'] == 'True')) if data.get('target_door_visit'): voters = voters.filter(target_door_visit=(data['target_door_visit'] == 'True')) if data.get('door_visit'): voters = voters.filter(door_visit=(data['door_visit'] == 'True')) if data.get('voted'): voters = voters.filter(voted=(data['voted'] == 'True')) if data.get('candidate_support'): voters = voters.filter(candidate_support=data['candidate_support']) if data.get('yard_sign'): voters = voters.filter(yard_sign=data['yard_sign']) if data.get('window_sticker'): voters = voters.filter(window_sticker=data['window_sticker']) if data.get('call_queue_status'): voters = voters.filter(call_queue_status=data['call_queue_status']) # Add donation amount filters min_total_donation = data.get('min_total_donation') max_total_donation = data.get('max_total_donation') if min_total_donation is not None or max_total_donation is not None: # Annotate each voter with their total donation amount, treating no donations as 0 voters = voters.annotate(total_donation_amount=Coalesce(Sum('donations__amount'), Value(0), output_field=DecimalField())) if min_total_donation is not None: voters = voters.filter(total_donation_amount__gte=min_total_donation) if max_total_donation is not None: voters = voters.filter(total_donation_amount__lte=max_total_donation) paginator = Paginator(voters, 50) page_number = request.GET.get('page') voters_page = paginator.get_page(page_number) context = { 'form': form, 'voters': voters_page, 'selected_tenant': tenant, 'call_form': ScheduledCallForm(tenant=tenant), } return render(request, "core/voter_advanced_search.html", context)""" import re # Find the function and its decorator # We search for the function name and then look for the role_required decorator above it pattern = r'@role_required\[.*?\]\s*,?\s*permission\s*=\s*