Search code examples
pythondjangomedia

Django media upload not working when uploading image through code


I have created a Django application in which i have a signup page which asks a user to upload their profile picture. When I'm uploading the profile picture through the Django admin panel, the images are being uploaded to the correct path and are being displayed in the website. However, the error comes when I directly select the image to upload when signing up and then When I click on the uploaded image in Django admin it shows page not found and the path to the image is being showed as C:\Users\hp\Workspace\findem\media\image.jpg

Settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
 os.path.join(BASE_DIR, 'findem/static')
]

# media folder settings
MEDIA_ROOT = os.path.join(BASE_DIR , 'media').replace('\\', '/')
MEDIA_URL = '/media/'

User Model

class UserProfile(AbstractBaseUser, PermissionsMixin):
    """Represents a user profile inside our system"""

    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255, default=profile_pic)
    profile_picture = models.ImageField(upload_to='photos/profile_pictures/', default='photos/User.jpg')
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    highest_degree_earned = models.CharField(max_length=255, blank=False)
    college_name = models.CharField(max_length=255, blank=False)
    graduation_year = models.IntegerField(default=2020, blank=False)

Template :

   <form class="needs-validation" novalidate autocomplete="off" 
action="{% url 'signup' %}", method="POST" >
{% csrf_token %}
<div id="Personal_Information">
<h5 class="loginSignup">Personal Information</h5>

   <div class="form-group row">
    <label for="inputprofile" class="col-sm-2 col-form-label">Profile Picture</label>
    <div class="col-sm-5">
      <div class="input-group">
      <div class="custom-file">
       <input type="file" accept="image/png, image/jpeg, image/gif" class="custom-file-input" id="inputprofile" name="inputprofile">
       <label class="custom-file-label" for="inputprofile" aria-describedby="inputprofile">Choose file</label>
      </div>
     </div>
   </div>
  </div>

  <div class="form-group required row">
    <label for="inputname" class="col-sm-2 col-form-label">Full Name <span id="required-field">*
     </span>
    </label>

   <div class="col-sm-5">
     <input type="text" class="form-control" name="inputname" id="inputname" placeholder="Enter Your Full Name" required>
     <div class="valid-feedback">Looks good!</div>
     <div class="invalid-feedback">Please enter your full name.</div>
    </div>

  </div>

  <div class="form-group row">
    <label for="inputemal" class="col-sm-2 col-form-label">Email <span id="required-field">*</span></label>
     <div class="col-sm-5">
       <input type="email" class="form-control" id="inputEmail" name="inputEmail" placeholder="Enter a Valid Email Address" required>
       <div class="valid-feedback">Looks good!</div>
       <div class="invalid-feedback">Please provide a valid email.</div>
    </div>
  </div>

<div class="form-group row">
    <label for="inputPassword" class="col-sm-2 col-form-label">Password <span id="required-field">*</span></label>
     <div class="col-sm-5">
       <input type="password" class="form-control" id="inputPassword" name="inputPassword" placeholder="Choose a Password" required>
       <div class="valid-feedback">Looks good!</div>
       <div class="invalid-feedback">Please chose a valid password.</div>
    </div>
  </div>

  <button type="submit" class="btn btn-success mt-3" id="loginButton">Sign Up</button>
</form>

view :

def signup(request):
"""View for Signing-up into the system"""
if request.method == 'POST':

    # Get form value
    profile_picture = request.POST.get('inputprofile')
    name = request.POST.get('inputname')
    email = request.POST['inputEmail']
    password = request.POST['inputPassword']
    highest_degree_earned = request.POST['inputDegree']
    college_name = request.POST['CollegeName']
    graduation_year = request.POST['inputGradYear']
    skill_1 = request.POST['upload_skill1']
    skill_2 = request.POST.get('upload_skill2', '')
    skill_3 = request.POST.get('upload_skill3', '')
    skill_4 = request.POST.get('upload_skill4', '')
    skill_5 = request.POST.get('upload_skill5', '')
    skill_6 = request.POST.get('upload_skill6', '')
    join_date = datetime.now()


    # Check Username
    if UserProfile.objects.filter(name=name).exists():
        messages.error(request, "That Name already taken")
        return redirect('signup')
    # Check email
    else:
        if UserProfile.objects.filter(email=email).exists():
            messages.error(request, "That email is being used")
            return redirect('signup')
        else:
            # Looks Good
            user = UserProfile.objects.create_user(profile_picture=profile_picture, name=name, email=email, 
            password=password, highest_degree_earned=highest_degree_earned, college_name=college_name, 
            graduation_year=graduation_year, skill_1=skill_1, skill_2=skill_2, skill_3=skill_3, skill_4=skill_4,
            skill_5=skill_5, skill_6=skill_6, join_date=join_date)

            # #Login after register
            # auth.login(request, user)

            user.save()
            messages.success(request, "You are now registered and can log in")
            return redirect('login')

else:    
    return render(request, 'pages/signup.html')

Solution

  • Change your form tag to be be like this :

    <form class="needs-validation" novalidate autocomplete="off" 
    action="{% url 'signup' %}", method="POST" enctype="multipart/form-data">
    

    add request.FILES to profile_picture like that :

        profile_picture = request.FILES.get('inputprofile') or None
    

    Than in your create request you do that :

            else:
            if UserProfile.objects.filter(email=email).exists():
                messages.error(request, "That email is being used")
                return redirect('signup')
            else:
                # Looks Good
    
                if profile_picture != None
                    user = UserProfile.objects.create_user(profile_picture=profile_picture, name=name, email=email, 
                        password=password, highest_degree_earned=highest_degree_earned, college_name=college_name, 
                        graduation_year=graduation_year, skill_1=skill_1, skill_2=skill_2, skill_3=skill_3, skill_4=skill_4,
                        skill_5=skill_5, skill_6=skill_6, join_date=join_date)
                else:
                    user = UserProfile.objects.create_user(name=name, email=email, 
                        password=password, highest_degree_earned=highest_degree_earned, college_name=college_name, 
                        graduation_year=graduation_year, skill_1=skill_1, skill_2=skill_2, skill_3=skill_3, skill_4=skill_4,
                        skill_5=skill_5, skill_6=skill_6, join_date=join_date)
    
    

    For the default picture try to change it to this :

     profile_picture = models.ImageField(upload_to='photos/profile_pictures/', default='/media/photos/User.jpg')