0

I have a homepage which currently runs a forloop to show all users.

{% for user in users %}

On that same page, there is a form to filter by radius (km) to see users close to you.

Currently, after you submit a radius to filter the users, nothing is returned because there is no

{% for user in location %} forloop yet.

I know I need some

{% if xxx %} {% else %} {% endif %}

statements but I'm unsure how to write them.

Essentially, if no filter is selected / radius is submitted I want to return all users (like it does right now). But if a radius is submitted or a filter is applied, I want the page to return the results of the queryset / multiple querysets.

Many thanks and any suggestions on cleaning up my code are always appreciated as I am a beginner.

views.py

class ConnectView(View):
    template_name = 'connect/home.html'
    def get(self, request, *args, **kwargs):
        context = {
            'users': User.objects.exclude(username=request.user),
            'friends': Friend.objects.filter(current_user=request.user),
        }
        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):
        location = Location(latitude=request.POST['latitude'], longitude=request.POST['longitude'], user = request.user)
        location.save()
        return JsonResponse({'message': 'success'})

def location(request):
    if request.POST:
        radius_km = request.POST.get('radius', 0)
        queryset = User.objects.annotate(
            radius_sqr=pow(models.F('loc__latitude') -
            request.user.loc.latitude, 2) + pow(models.F('loc__longitude') -
            request.user.loc.longitude, 2)
            ).filter(
            radius_sqr__lte=pow(int(radius_km) / 9, 2)
            ).exclude(username=request.user)
        context = dict(location=queryset)
        return render(request, 'connect/home.html', context)

urls.py

urlpatterns = [
    path('', connect_views.ConnectView.as_view(), name='connect_home'),
    path('location', connect_views.location, name='location'),

connect.html

  <h1>Connect with people near you.</h1>
            <!-- GET window.location IP Address / lat lon coordinates -->
            <p id="demo"></p>
            <button onclick="getLocation()" class="btn btn-warning" id="confirm">1. Fetch Location</button>
            <button type="submit" id="btn_submit" class="btn btn-success" disabled>2. Submit Location </button>
            <!-- enter radius to filter by location -->
            <form action="location" method="POST">
              {% csrf_token %}
              <input type="number" name="radius">
              <input type="submit" value="filter by kilometers">
            </form>

{% for user in users %}
       <h4>{{ user.first_name }} {{ user.last_name }}
       {{ user.profile.age }} / {{ user.profile.city }}
       {{ user.profile.bio }}</h4>
{% endfor %}
7
  • You're not quite clear on where your problem is. Are you asking about what to do before the user has submitted the radius, or what to do when the user has submitted the radius but there are no matching users? Commented Feb 13, 2019 at 16:16
  • I am asking about what to do when the user has submitted the radius and there are matching users. Right now, a list of all users is being rendered out before the user submits a radius. After they submit a radius, I would like that list of all users to change to reflect the result of the queryset. So essentially, I think I need 2 forloops on my homepage. One for for user in users to return all users if no radius has been entered and for user in location if a radius has been submitted. I'm struggling with writing the if then statements for that to occur. Commented Feb 13, 2019 at 16:20
  • What? No you don't. I think the confusion is coming from this separate location view. How is that called and how does it relate to ConnectView? Commented Feb 13, 2019 at 16:22
  • The location view is the function that takes in the radius in order to generate out a queryset of users. location view is called via a submit form on the ConnectView page Commented Feb 13, 2019 at 16:24
  • Well maybe you should show that whole template. Commented Feb 13, 2019 at 16:25

1 Answer 1

1

You don't need two for loops. The only thing wrong with what you have is that your location view sends its users queryset as location instead of users. Change that (note, there's no reason to use the dict() function):

    context = {'users': queryset}
    return render(request, 'connect/home.html', context)
Sign up to request clarification or add additional context in comments.

4 Comments

Ha ha...wow...I way overthought that one! Really appreciate the help Daniel.
Hi Daniel, one last question if you have time. If the queryset returns none, what is the best way to render a no matches text instead of displaying an empty page?
The {% for %} tag has an {% empty %} clause which is for exactly this purpose.
Thanks again, I had the empty tag on the wrong page!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.