Search code examples
javascriptpythonjquerydjangoajax

AJAX request to Django view and python print to terminal doesn't do anything


I am working on a Django website for the nonprofit. I am on the profile images part. I am trying to upload images using the image as a button to submit. I have the file chooser that opens. Then, it submits upon finishing choosing a file. It should be saving the image uploaded to the Django database. So far, my AJAX request to the Django view, its success function works correctly. However, when I try to print to the terminal my test, nothing is printed in the python terminal. Also, the image doesn't update appropriately.

# source\templates\profile-pages\child-profile.html
...
<script>
$(document).ready(function () {

    if (typeof jQuery == 'undefined') {
    console.error('jQuery is not loaded!');
    } else {
      console.log('jquery is loaded');
    }
    // Get the image and input elements
    var imageButton = document.getElementById("image-button");
    var fileInput = document.getElementById("file-input");

    // Add a click event listener to the image element
    imageButton.addEventListener("click", function (e) {
      // Simulate a click on the hidden input element
      e.preventDefault();
      fileInput.click();
    });

    // Add a change event listener to the input element
    fileInput.addEventListener("change", function (e) {
      e.preventDefault();
      // Get the selected file from the input element
      var file = fileInput.files[0];
      console.log(file);
      console.log(typeof file);
      // Create a URL for the file object
      if (
        !(
          file.type == "image/jpeg" ||
          file.type == "image/jpg" ||
          file.type == "image/png"
        )
      ){
        alert("Image must be jpeg, jpg or png");
        $("#fileInput").val("");
        return False;
      }
      var formData = new FormData();
        formData.append("newPic", file);
      // Update the image source with the file URL
      // imageButton.src = url;
      $('#submitBtn').submit(submitF(e, formData));
    });

    function submitF(e, pic) {
      e.preventDefault();

      // if (!$("#fileInput").val()) {
      //   alert("Please choose a file");
      // }

      // var formData = new FormData(this);
      console.log("form data. #picform submitted");
      $.ajax({
        headers: {
    'X-CSRFToken': $("input[name=csrfmiddlewaretoken]").val(),
},
        url: "{% url 'users:profile' %}",
        // url: "/profile",
        data: {
          newPic: pic,
          csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val(),
        },
        method: "POST",
        contentType: false, // Set contentType and processData to false for file uploads
        processData: false,
        success: function (data) {
          alert("success ");
        },
        error: function (xhr, status, error) {
          console.log("AJAX error: ", status, error);
        },
      });

      // $("#imageButton").attr("src", formData);
    }
  });
</script>
...
{% load crispy_forms_tags %}
    <div id="profile-row" class="row g-3">
      <div id="profile-img-container" class="col-md-5">
        <form id="picForm" method="POST" enctype="multipart/form-data">
          {% csrf_token %}
          <input
            id="file-input"
            type="file"
            name="picture"
            accept="image/*"
            style="display: none"
          />
          {% if request.user.profile_pic.url %}
          <img
            id="image-button"
            src="{{ request.user.profile_pic.url }}"
            style="
              width: 100px;
              height: 100px;
              border: 1px solid black;
              cursor: pointer;
            "
          />

          {% elif request.user.profile_pic.url == None %}
          <img src="{% static '/profile-images/default.png' %}" />
          <p>Test</p>
          {% endif %}
          <button type="submit" id="submitBtn" value="Submit">Submit</button>
        </form>
      </div>
...
# users\views.py
...
@login_required
def profile(request):
    user = get_object_or_404(afbUsers)
    if request.method == 'POST':
        new_pic_file = request.FILES.get('newPic')

        if new_pic_file:
            print('testing 123', new_pic_file.name)

            # Update the logic based on your model and how you want to handle the file
            user.profile_pic = new_pic_file
            user.save()

            messages.success(request, 'Profile image update success!')
            return JsonResponse({'status': 'success'})
        else:
            messages.error(request, 'No file uploaded.')
            return JsonResponse({'status': 'error', 'message': 'No file uploaded.'})
    context = {'user': user}
    return render(request, 'profile-pages/child-profile.html', context)
...

Solution

  • Had to have a separate view to return JsonResponse and render.

    @login_required
    def profile(request, user):
        all_events = Events.objects.all()
        calendaruser = get_object_or_404(afbUsers, pk=request.user.id)
        form = CalendarTimeZoneForm(request.POST or None, instance=calendaruser)
        profile = get_object_or_404(afbUsers, pk=user)
        gallery_entries = GalleryEntry.objects.all()
        publicform = UserSettingsForm(request.POST or None, instance=profile)
    
        if request.method == "POST" and form.is_valid():
            form.save()
            # Redirect or indicate success
        context = {
            "userprofile": profile,
            "publicform": publicform,
            "user": user,
            "gallery_entries": gallery_entries,
            "events": all_events,
            "calendaruser": calendaruser,
            "form": form,
        }
        return render(request, "profile-pages/child-profile.html", context)
    
    
    def upload_profile_pic(request):
        # user = get_object_or_404(afbUsers, child_name = request.afbUsers.child_full_name, profile_image = request.afbUsers.profile_pic)
        user = request.user.id
        if request.method == "POST":
            new_pic_file = request.FILES.get("newPic")
    
            if new_pic_file:
                print("testing 123", new_pic_file.name)
                newPic = afbUsers.objects.get(pk=user)
                # Update the logic based on your model and how you want to handle the file
                newPic.profile_pic = new_pic_file
                newPic.save()
    
                return JsonResponse({"status": "success"})
            else:
                pass
                return JsonResponse({"status": "error", "message": "No file uploaded."})