Search code examples
pythondjangoimagefield

Django returns only default image URL


I am new to Django and building a simple social media type app for adding and viewing posts.

I am using admin side to upload profile images for users and it works well. I am yet to create a frontend to upload profile images.

I am using PostgreSQL and I can query to see the correct URLs being saved in the table for profile images. But when I try to fetch these images and render, the default image (set in models.py) always renders. I am able to open the right images from admin side but Django only returns the default image.

My frontend has Javascript in which I am using fetch API to get URLs of profile images. It works well except it returns only the default image.

Please help me find out where I am going wrong or why only 'defaultpp.jpg' always shows up. I have tried using print statements in models.py and views.py and only see the URL for 'defaultpp.jpg' being returned.

models.py

def user_directory_path(instance, filename):
    return f'{instance.profile_user.id}/{filename}'

class User(AbstractUser):
    def __str__(self):
        return f"User ID: {self.id} Username: {self.username}"

class UserProfile(models.Model):
    profile_user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    profile_picture = models.ImageField(upload_to = user_directory_path, blank=True, null=True, default='defaultpp.jpg')
    

    def __str__(self):
        return f"User: {self.profile_user} Username: {self.profile_user.username}"


    @property
    def get_profile_picture_url(self):
        if self.profile_picture and hasattr(self.profile_picture, 'url'):
            return self.profile_picture.url

settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DEBUG = True

STATIC_URL = '/static/'

# Root and URL for uploaded files to be stored
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

views.py

def profile_image(request, user):
    
    user = User.objects.get(username=user)
    profile = UserProfile(profile_user=user)
    profile_picture_url = str(profile.get_profile_picture_url)

    return JsonResponse({"image": profile_picture_url}, safe=False)

profile_picture_url = str(profile.get_profile_picture_url) here returns URL for 'defaultpp.jpg' every time even though I have uploaded some other image there

urls.py

from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("network.urls")),
]  + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

HTML and JS

<script>

    //funtion to fetch profile image for each post and add it to the media object
    function post_profile_image()
    {
        document.querySelectorAll('.profileimage').forEach(profileimage => {
            let user = profileimage.dataset.user;

            function assign_image(imageURL)
            {
                document.querySelectorAll(`.${user}`).forEach(e => {
                    e.src = imageURL;
                });
            }

            fetch(`profile/image/${user}`)
            .then(response => response.json())
            .then(image => {
                let imageURL;
                imageURL = image.image;
                assign_image(imageURL);
            })
            .catch(function() {
                console.log("Could not fetch profile image");
            });
            
        });
    }

    document.addEventListener('DOMContentLoaded', function() {
        //funtion to fetch profile image for each post and add it to the media object
        post_profile_image();
    });

</script>

<img class="img-thumbnail mr-3 profileimage {{ post.post_user }}" data-user='{{ post.post_user }}' src="" alt="profile image">

Folder structure

├───media
│   ├───1
│   ├───2
│   ├───29
│   ├───3
│   ├───34
│   ├───5
│   ├───7
│   
├───network
│   ├───migrations
│   │   └───__pycache__
│   ├───static
│   │   └───network
│   ├───templates
│   │   └───network
│   └───__pycache__
└───project4
    └───__pycache__

The profile images I upload from admin side go into each of the numbered folders (user IDs) in the media folder.


Solution

  • I was able to fix this by correcting the view.

    profile = UserProfile.objects.get(profile_user=user)