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.
I was able to fix this by correcting the view.
profile = UserProfile.objects.get(profile_user=user)