1

Hello I'm trying to develop a blog using django as a backend and react on the frontend. i've written a map function on the frontend to loop through the blog articles, all other field elements appears but the images don't render. the following are some files that i think might be relevenat for this case

models.py

from django.db import models
from django.contrib.auth import get_user_model

# Create your models here.

class Category (models.Model):
    name = models.CharField(max_length=150)

    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name


class Post (models.Model):
     
    title = models.CharField(max_length=200)
    description = models.CharField(max_length=500)
    body = models.TextField(null=True)
    published = models.DateTimeField('Date published', auto_now_add=True)
    modified = models.DateTimeField('Date published', auto_now_add=True)
    category = models.ForeignKey(Category, default="", verbose_name='Categories', on_delete=models.SET_DEFAULT )
    author = models.ForeignKey(get_user_model(), default=1, on_delete=models.SET_DEFAULT)
    image = models.ImageField(default='default/no_image.png', upload_to='blog/%Y/%m/%d', max_length=255)

    def __str__(self):
        return self.title

serializer.py

from rest_framework import serializers
from django.contrib.auth.models import User
from .models import *

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = '__all__'

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

class UserRegSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=150)
    username = serializers.CharField(max_length=100, write_only=True)

    def create(self, validated_data):
        user = User.objects.create(
            username = validated_data['username'],
            password = validated_data['password']
        )

        return user


urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('category/', views.category, name='category'),
    path('users/', views.users, name='users'),
    path('user-registration/', views.user_registration, name='user-registration'),
]

views.py

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .serializers import *
from .models import *
from django.contrib.auth.models import  User

# Create your views here.

@api_view(['GET'])
def home (request):
    posts = Post.objects.all()
    serialize = PostSerializer(posts, many=True)
    return Response(serialize.data)

@api_view(['GET'])
def category(request):
    cat = Category.objects.all()
    serialize = CategorySerializer(cat, many=True)
    return Response(serialize.data)

@api_view(['GET'])
def users(request):
    users = User.objects.all()
    serialize = UserSerializer(users, many=True)
    return Response(serialize.data)

@api_view(['POST'])
def user_registration(request):
    serializer = UserRegSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.save()
        return Response(serializer.dat, status=status.HTTP_201_CREATED)
    
    return Response(serializer(serializer.errors, status=status.HTTP_400_BAD_REQUEST))

Home.jsx

import React, {useEffect} from 'react'
import { useDispatch, useSelector} from 'react-redux'
import { getPostStatus, selectAllPosts, getPostError, fetchPosts } from '../features/blog/BlogSlice'
import BlogExcerpt from '../features/blog/BlogExcerpt'
import SidePannel from './SidePannel'


const Home = () => {

  const dispatch = useDispatch()

  const posts = useSelector(selectAllPosts)
  const postStatus = useSelector(getPostStatus)
  const errors = useSelector(getPostError)

  useEffect(() => {
    if (postStatus === 'idle'){
      dispatch(fetchPosts())
    }
  },[dispatch, postStatus])

  let content;
  if (postStatus === 'loading'){
    content = <div className='center'>
      loading...
    </div>
  } else if (postStatus === 'succeeded'){
    content = posts.map((post) => 
      <BlogExcerpt key={post.id} postId={post.id} post={post}/>
    )
  }else if (postStatus === 'failed')
{
  content = <p>failed {errors} </p>
}

console.log(content)
  return (
    <div className='container m-auto mt-5'>
        <div className='grid grid-cols-3 gap-4'>
            <div className='col-span-2 shadow-lg text-center pl-12 py-3'>
               <div className='container px-auto grid grid-cols-2 gap-2'> { content } </div>
               <img src='http://127.0.0.1:8000/media/blog/2024/02/17/team-1.jpg' alt='web' />
               
            </div>
            <div className=''>
                <SidePannel/>
            </div>
        </div>
        
    </div>
     

  )
}

export default Home

BlogExcerpt

import React from 'react'

const BlogExcerpt = ({post, postid}) => {
  return (
    <div>
      <p>{post.title}</>
      <img src={post.image} alt='yep' />
    </div>
  )
}

export default BlogExcerpt

BlogSlice.jsx

import axios from 'axios';
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';


const apiUrl ='http://127.0.0.1:8000';


const initialState = {
    posts: [],
    status: 'idle',
    error: null,
    categoryFilter: null,
}

export const fetchPosts = createAsyncThunk('post/fetchPosts', async () => {
    const response = await axios.get(apiUrl);
    return response.data
});

const postslice = createSlice({
    name: 'posts',
    initialState,
    reducers: {
        setCategoryFilter: (state, action) => {
            state.categoryFilter = action.payload
        },
    },

    extraReducers(builder){
        builder
            .addCase(fetchPosts.pending, (state, action) => {
                state.status = 'loading';
            })
            .addCase(fetchPosts.fulfilled, (state, action) => {
                state.status = 'succeeded';
                state.posts = action.payload;
            })
            .addCase(fetchPosts.rejected, (state, action) => {
                state.status = 'failed';
                state.error = action.error.message;
            })
    }
})

export const {setCategoryFilter} = postslice.actions;

export const selectAllPosts = (state) => state.posts.posts;
export const getPostStatus = (state) => state.posts.status;
export const getPostError = (state) => state.posts.error;
export const selectCategoryFilter = (state) => state.posts.categoryFilter;

export default postslice.reducer;

in fact when i inspect the img element, the source url is "http://localhost:5173/media/blog/2024/02/17/team-1.jpg" however, i think the url should have been "http://localhost:8000/media/blog/2024/02/17/team-1.jpg". in fact when i enter this later url I'm able to retrieve the image as it is th actual url to the media folder in the django backend. any help would be greatly appreciated.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.