1

I have been trying to make my code able to post images but when I create the post, the picture doesnt appear but the image gets save on media/images I was wondering if there is any way to make the code work, ther might be something wrong in the base.html when I call the image {{ request.user.image.url }}

views.py

     def create(request):
        if request.method == 'POST':
            created_date = timezone.now()
            header1 = request.POST['header']
            content1 = request.POST['content']
            user = request.user
            uploded_file = request.FILES['image']
            created_obj = Create.objects.create(added_date=created_date, title=header1, content=content1, user=user, image=uploded_file)
            created_obj.save()
            print('create created')
            return redirect('home')
        else:
            print('create not created')
            return render(request, 'create.html')

models.py

    class Create(models.Model):
        added_date = models.DateTimeField()
        title = models.CharField(max_length=200)
        content = models.CharField(max_length=200)
        image = models.ImageField(null=True, blank=True, upload_to='images/')
        user = models.ForeignKey(User, related_name='user', on_delete=models.CASCADE, default=1)

    class Profile(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE)
        image = models.ImageField(default='default.jpg', upload_to='profile_pics')

        def __str__(self):
            return f'{self.user.username} Profile'

create.html

    {% extends 'home.html' %}
    {% block body %}
    <div style="margin-top: 200px; margin-left:200px;">
        <form action="create" method="POST" enctype="multipart/form-data">
            {% csrf_token %}
            <input type="text" name="header" placeholder="Add here...">
            <input type="text" name="content" placeholder="Add here...">
            <input type="file" name="image">
            <button type="submit"name="action" class="btn btn-primary mb-2">submit</button>
        </form>
    </div>
    {% endblock %}

base.html

    {% extends 'home.html' %}
    {% block body %}
    <ul action="{% url 'create' %}" class="container-sm list-group" style="margin-top: 200px;">
        {% for created_post in created_posts %}
        <li class="list-group-item">{{ created_post.title }}
          <a href="{% url 'profile_pk' pk=created_post.user.pk %}">{{ created_post.user }}</a>
          <img class="image" src="{{ create.image.url }}">
          <p>{{ created_post.content }}</p>
          <div class="float-right">
            <form action="delete_create/{{ created_post.id }}/" action="post">
              <button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
            </form>
          </div>
          <div class="float-right">
            <a href="{% url 'edit' created_post.id %}" class="btn btn-outline-warning btn-sm" style="margin-right: 5px;" role="button">Edit</a>
          </div>
        </li>     
        {% endfor %}            
    </ul>
    {% endblock %}
Juan Martin Zabala
  • 673
  • 1
  • 7
  • 17

1 Answers1

0

In most of the websites, we often deal with media data such as images, files etc. In django we can deal with the images with the help of model field which is ImageField.

In this article, we have created the app image_app in a sample project named image_upload.

The very first step is to add below code in the settings.py file.

filter_none
brightness_4
MEDIA_ROOT =  os.path.join(BASE_DIR, 'media') 
MEDIA_URL = '/media/'

MEDIA_ROOT is for server path to store files in the computer. MEDIA_URL is the reference URL for browser to access the files over Http.

In the urls.py we should edit the configuration like this

if settings.DEBUG:

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

A sample models.py should be like this, in that we have created a Hotel model which consists of hotel name and its image. In this project we are taking the hotel name and its image from the user for hotel booking website.

filter_none
brightness_4
# models.py 
 class Hotel(models.Model): 
    name = models.CharField(max_length=50) 
    hotel_Main_Img = models.ImageField(upload_to='images/') 
//Here upload_to will specify, to which directory the images should reside, by default django creates the directory under media directory which will be automatically created when we upload an image. No need of explicit creation of media directory.

We have to create a forms.py file under image_app, here we are dealing with model form to make content easier to understand.

filter_none
brightness_4
# forms.py 
from django import forms 
from .models import *



class HotelForm(forms.ModelForm): 

    class Meta: 
        model = Hotel 
        fields = ['name', 'hotel_Main_Img'] 

Django will implicitly handle the form verification’s with out declaring explicitly in the script, and it will create the analogous form fields in the page according to model fields we specified in the models.py file. This is the advantage of model form.

Now create a templates directory under image_app in that we have to create a html file for uploading the images. HTML file should look like this.

filter_none
edit
play_arrow

brightness_4
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Hotel_image</title> 
</head> 
<body> 
    <form method = "post" enctype="multipart/form-data"> 
        {% csrf_token %} 
        {{ form.as_p }} 
        <button type="submit">Upload</button> 
    </form> 
</body> 
</html> 

When making a POST request, we have to encode the data that forms the body of the request in some way. So, we have to specify the encoding format in the form tag. multipart/form-data is significantly more complicated but it allows entire files to be included in the data.

The csrf_token is for protection against Cross Site Request Forgeries.

form.as_p simply wraps all the elements in HTML paragraph tags. The advantage is not having to write a loop in the template to explicitly add HTML to surround each title and field.

In the views.py under image_app in that we have to write a view for taking requests from user and gives back some html page.

filter_none
brightness_4
from django.http import HttpResponse 
from django.shortcuts import render, redirect 
from .forms import *

# Create your views here. 
def hotel_image_view(request): 

    if request.method == 'POST': 
        form = HotelForm(request.POST, request.FILES) 

        if form.is_valid(): 
            form.save() 
            return redirect('success') 
    else: 
        form = HotelForm() 
    return render(request, 'hotel_image_form.html', {'form' : form}) 




def success(request): 
    return HttpResponse('successfully uploaded') 

whenever the hotel_image_view hits and that request is POST, we are creating an instance of model form form = HotelForm(request.POST, request.FILES) image will be stored under request.FILES one. If it is valid save into the database and redirects to success url which indicates successful uploading of the image. If the method is not POST we are rendering with html template created.

urls.py will look like this –

filter_none
brightness_4
from django.contrib import admin 
from django.urls import path 
from django.conf import settings 
from django.conf.urls.static import static 
from .views import *

urlpatterns = [ 
    path('image_upload', hotel_image_view, name = 'image_upload'), 
    path('success', success, name = 'success'), 
] 

if settings.DEBUG: 
        urlpatterns += static(settings.MEDIA_URL, 
                              document_root=settings.MEDIA_ROOT) `enter code here`
Jobin S
  • 89
  • 1
  • 8