global variable not updating in django view

Please refer to https://stackoverflow.com/questions/61194496/global-variable-not-updating-in-django-view for details of my problem. This is urgent!

Globals python variables are not appropriate within a web service framework. You need to either save your data in a database or in one of the caching frameworks.

I don’t really want to save the variable e to the database. How else could I tackle this problem?

You could hook into one of the Django caching solutions to keep it locally. (This is assuming that “e” is truly global across all requests from all users - and that it only exists for the period of time that the web application is running. But if you want “e” persisted across application or server restarts, then yes, a database table is a fine place for it.)

Essentially, e should only get passed to the context dict when it has the value from my AJAX form, and render inside the modal appropriately. Could you give me a coding example on how to do this? I am quite new to Django.

I’m going to try to rephrase this to help ensure I understand the situation:

  • The user enters data on a form
  • The form may or may not have data entered in field “e”
  • The form is POSTed via AJAX
  • The Django view (invoked by the AJAX call) returns something, where something may be different depending upon whether or not “e” is supplied.

Would you say this summary is accurate? If so, I’d probably need to see at least the view that the AJAX is submitting the form to. If that view is rendering a template, then it might be helpful to see what you want to have happen differently depending upon the presence or absence of “e”.

Screenshot 2020-04-14 at 10.53.01 AM

This is what I expect to happen. When “View Profile” is clicked, the UserProfileInfo of the corresponding user should be displayed in my modal(picture in next post). However, every time I click it, it displays it for devilz instead of devx, despite clicking the button for devx. This is because I have initially declared the value of e as h[0], which is devilz. However, shouldn’t it update once the button is clicked?
Hope this clarifies it.

Modal

Ahh, ok, now it’s becoming a lot clearer.

I don’t know how you’re activating the “View Profile” button in JavaScript, but what you want to do is create that button with the information needed to display the corresponding details.

For example, if this wasn’t AJAX, but instead regular links, the link would be created in your template with a reference to the primary key for those usernames. But since you’re doing this with AJAX, that means you’ve got some JavaScript involved, and that’s part of the picture.

So to be more specific, I’d need to know how you’re creating that grid that contains the “View Profile” button, and the JavaScript that is acting on that button, along with the view being invoked by the AJAX call.

Button code -

<button class="checkBTN" id="{{ x.user }}">View Profile</button>

AJAX call -

<script>

    $('.checkBTN').click(function(e) {
        e.preventDefault();
      let id = $(this).attr('id');
      $.ajax({
          type: 'POST',
          url: '{% url 'app1:view_profile' %}',
          data: {
              friend:id,
              csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
          },

          success: function() {
              document.getElementById('id01').style.display='block';
          }

       });
    });

</script>

modal code

<div id="id01" class="w3-modal">
    <div class="w3-modal-content w3-card-4">
      <header class="w3-container w3-teal">
        <span onclick="document.getElementById('id01').style.display='none'"
        class="w3-button w3-display-topright">&times</span>
        <h1><img src="https://cdn.discordapp.com/attachments/596570958601388078/596670448918593550/Screenshot_2019-07-05_at_5.24.37_PM.png" width="50" height="50"></h1>
      </header>
      <div class="jumbotron">
          <h3>User: {{ e }}</h3>
          <h3>Favourite Song:  {{ e.fav_song }}</h3>
          <h3>Favourite Artist:  {{ e.fav_artist }}</h3>
          <br><br>
          <h3>Most Played Artist:  {{ e.most_played_artist }}</h3>
          <h3>Most Played Song:  '{{ e.most_played_song }}'</h3>
      </div>
      <footer class="w3-container w3-teal">
          <p><center>GENSIC PROFILES</center></p>
      </footer>
    </div>
  </div>

views.py

def view_profile(request):

    g = Friend.objects.all()
    j = forms.FriendForm()
    s = forms.SearchForm()
    h = UserProfileInfo.objects.all()

    global term
    term = []
    global r
    r = []
    global e
    e = h[0]
    global friend_arr
    friend_arr = []
    global messages
    messages = []

    if len(g) != 0:
        for x in g:
            if x.user == request.user.username:
                friend_arr.append(x)
            else:
                pass

    if request.method == "POST":

        s = forms.SearchForm(request.POST)
        j = forms.FriendForm(request.POST)

        if request.is_ajax():

            if list(request.POST)[0] == 'friend':
                friend = request.POST['friend']

                for x in range(0, (len(h) - 1)):
                    if str(h[x]) == str(friend):
                        e = h[x]
                        break
                    else:
                        pass

            elif list(request.POST)[0] == 'to_be_messaged':
                t6t6 = request.POST['to_be_messaged']
                new_arr = t6t6.split('+')
                global action
                global user
                action = new_arr[0]
                user = new_arr[1]

                messages = MessageModel.objects.filter(user=request.user.username, to_user=user)

            else:
                d = MessageModel.objects.get_or_create(
                    user=request.user.username,
                    to_user=user,
                    message=request.POST['message_text'],
                )[0]
                d.save()

            # return HttpResponse('')

        print(e)

        if s.is_valid():
            term = ArtistCount.objects.filter(user__icontains=(s.cleaned_data['friend']))

        if j.is_valid() and request.POST.get('sReq') is not None:
            t = Friend.objects.get_or_create(
                user=request.user.username,
                friend=request.POST.get('sReq'),
            )[0]
            t.save()

            r = Friend.objects.get_or_create(
                user=request.POST.get('sReq'),
                friend=request.user.username,
            )[0]
            r.save()

    args = {'g': g, 'j': j, 's': s, 'term': term, 'r': r, 'e': e, 'friend_arr': friend_arr}

    return render(request, 'app1/friends.html', args)

I hope this is enough.

@KenWhitesell what could be the problem here?

Unfortunately, quite a bit.

First, the primary question being asked, regarding the passing of information from your form:

You’re getting the id from the field, you want to include that in your url. So if you do something like:

url: '{% url 'app1:view_profile' %}'+id+'/',

This will concatenate the id to the URL, making it accessible to the view as a parameter.
You’ll also need to create another url entry to accept this form of the url.

(There are other ways that “look” better, but this should fundamentally work.)

But there are a number of general comments I’d make about your view.

  • You’ll find things to be a whole lot cleaner if you create a different view for your AJAX calls than for your page views.

  • There’s no need to read and save all instances of the objects at the top of the function. Use the Django query facility for searching your data when you need it.

  • It looks like you might be trying to accumulate data across multiple requests. That’s when you want to start using Django sessions

What I’m not seeing are any of the common coding patterns that I would expect to see in a Django application. If you haven’t already done so, I strongly encourage you to work through the Writing your first Django app tutorial. You’ve got some of the basics down, so you might be able to jump in at Part 3 after briefly reviewing the first two parts. This will save you time in the long run, by helping you see how Django expects certain things to be done.

Ken

Ok, got it. The thing is, I have to submit this app today. How do I include this in the url?