Django: How to go to a URL with select option using GET and views.py instead of a pure JavaScript approach

I show two solutions, one with GET, the other with Javascript. In both I need to double click the back button to come back to the previous page. I think this is a Django problem.

GET case

In templates I have the following form:

<form id="form-user" action="" method="GET">
<select id="user" data-slug="{{x.user}}" onChange=selectChange(this)>
    <option value="view">View</option>
</select>
</form>
<script>
function selectChange(select) {
    var selectID = select.id;
    var value = select.value;
    
    if ($('#'+selectID).data('slug')) {
        var my_slug = $('#'+selectID).data('slug');
        var my_url_creator = "{% url 'profiles:profile-detail' slug=none %}".replace(/none/, my_slug.toString());
    }
    
    if (value == 'view'){
        $("#form-"+selectID).attr("action", my_url_creator);
        $("#form-"+selectID).submit();
    }  
}

In views.py I have:

 class ProfileView(DetailView):
    model = Profile

    def get_object(self, *args, **kwargs):
        myslug = self.kwargs.get('slug')
        user = User.objects.get(username=myslug)
        profile = Profile.objects.get(user=user)
        return profile

This approach takes me to the profile page of {{x.user}}=user1, however when I click the backward button in the browser, it goes from mypath/user1 to mypath/user1?. I don't like this ?. To go back to the previous page I would need to click the backward button twice. I would like to click it only once and remove this ? transition step.

Javascript case

views.py doesn't change as it is not needed. template is quite similar, we just remove the method="GET" in the HTML form tag, while in the javascript we only change the following:

if (value == 'view'){
            window.location.href = my_url_creator;
        }  

Here also, I manage to go to the user page, however to come back to the previous page I need a double click, in this cases it goes from mypath/user1 to mypath/user1 and then to the previous case.

I do believe it is a django problem but I'm not sure if we can solve it

EDIT:

As suggested views.py is better written as:

def get_object(self, *args, **kwargs):
        slug = self.kwargs.get('slug')
        return get_object_or_404(Profile, user__username=slug)

However this doesn't fix the problem.

What about just a link?

<a href="{% profiles:profile-detail slug=x.user %}">View</a>

Through CSS, you can style the link as a button or something else. This will trigger a GET request. A POST request makes not much sense, since you do not change the state: GET requests are supposed to have no side-effects, and POST requests are normally used to create, update, or remove data.

Your view can also be simplified: fetching the User is not necessary:

from django.shortcuts import get_object_or_404


class ProfileView(DetailView):
    model = Profile

    def get_object(self, *args, **kwargs):
        return get_object_or_404(Profile, user__username=myslug)
Back to Top