Gahan Vig
Gahan Vig

Reputation: 216

How can I upload an image to database via HTML form in Django?

I am creating a Blog using Django. I have created a html form where the user can add title and content to his/her blog and upload images for the blog to the database.

HTML Form

    <form method="post" action="/addPost" class="container my-4">
        {% csrf_token %}
        <div class="mb-3">
            <label class="form-label">Blog Title</label>
            <input type="text" name="blogTitle" required class="form-control">
        </div>
        <div class="mb-3">
            <label class="form-label">Blog Image (Optional)</label>
            <input class="form-control" type="file" name="blogImg">
        </div>
        <div class="mb-3">
            <label class="form-label">Blog Content</label>
            <textarea class="form-control" name="blogContent" required rows="3"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">Create</button>
    </form>

When I try to upload image through admin panel I am able to upload image easily but when I try to do the same through the html form I am unable to do so.

BlogPost Model

    class BlogPost(models.Model):
        Sno = models.AutoField(primary_key=True)
        Writer = models.ForeignKey(User, on_delete=models.CASCADE)
        BlogImage = models.ImageField(upload_to="static/img", blank=True)
        BlogTitle = models.CharField(max_length=1000)
        BlogContent = models.TextField()
        Slug = models.SlugField(default='')
        Date = models.DateTimeField()

AddBlogPost Function

    def addPost(request):
        if request.user.is_authenticated:
            if request.method == "POST":
                image = request.POST.get("blogImg")
                title = request.POST.get("blogTitle")
                content = request.POST.get("blogContent")
                user = request.user
                slug = str(title).lower().replace(" ", "-")
                datetime = now()
                
                BlogPost.objects.create(Writer=user, BlogImage=image, BlogTitle=title, BlogContent=content, Slug=slug, Date=datetime)
                return redirect("/")
            return render(request, "addBlogPost.html")
        else:
            return HttpResponse("404 not found")

urls.py of app

from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("", views.index, name="Main"),
    path("addPost", views.addPost, name="addPost"),
    path("signup", views.signUp, name="signUp"),
    path("logout", views.Logout, name="Logout"),
    path("login", views.Login, name="Login"),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

What should I do to upload files through the html form too so that they are saved in the static folder too?

Upvotes: 1

Views: 798

Answers (2)

caleo
caleo

Reputation: 96

You must include the enctype="multipart/form-data" attribute in the form html where you are including image/file uploads.

<form method="post" enctype="multipart/form-data" action="/addPost" class="container my-4">
    {% csrf_token %}
    <div class="mb-3">
        <label class="form-label">Blog Title</label>
        <input type="text" name="blogTitle" required class="form-control">
    </div>
    <div class="mb-3">
        <label class="form-label">Blog Image (Optional)</label>
        <input class="form-control" type="file" name="blogImg">
    </div>
    <div class="mb-3">
        <label class="form-label">Blog Content</label>
        <textarea class="form-control" name="blogContent" required rows="3"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
</form>

Edit your views.py change the following

image = request.POST.get("blogImg")

to

image = request.FILES.get("blogImg")

If that doesn't work you may also need to add MEDIA_ROOT & MEDIA_URL to settings.py and change your url patterns to this

urlpatterns = [
    path("", views.index, name="Main"),
    path("addPost", views.add_post, name="addPost"),
    path("signup", views.signUp, name="signUp"),
    path("logout", views.Logout, name="Logout"),
    path("login", views.Login, name="Login"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Upvotes: 2

Godda
Godda

Reputation: 1001

Well basically i think your problem comes from your html, you forgot to add accept="image/*" to your image field.i did just that and so it should work.


 <form method="post" action="" class="container my-4">
        {% csrf_token %}
        <div class="mb-3">
            <label class="form-label">Blog Title</label>
            <input type="text" name="blogTitle" id="id_blogTitle" required class="form-control">
        </div>
        <div class="mb-3">
            <label class="form-label">Blog Image (Optional)</label> <!--You omitted accept="image/*"-->
            <input class="form-control" type="file" name="blogImg" id=id_blogImg accept="image/*">
        </div>
        <div class="mb-3">
            <label class="form-label">Blog Content</label>
            <textarea class="form-control" name="blogContent" id="id_blogContent" required rows="3"></textarea>
        </div>
        <button type="submit" class="btn btn-primary">Create</button>
    </form>

Looking at your upload view.py i notice that you had datetime in the field which might be possibly an issue and also i didn't put the id variable in the template that could also have course it not to work.

 def addPost(request):
     if request.method == "POST":
        image = request.POST.get("blogImg")
        title = request.POST.get("blogTitle")
        content = request.POST.get("blogContent")
        slug = str(title).lower().replace(" ", "-")
        blog_data = BlogPost(Writer=user, BlogImage=image, 
                             BlogTitle=title, BlogContent=content,Slug=slug)
        blog_data.save()
        form = BlogPostForm(request.POST, request.FILES)
        if form.is_valid():
           form.save()
           return redirect("/")
        return render(request, "addBlogPost.html")
    else:
        return HttpResponse("404 not found")

okay here i am going to create form to handle the Blog object uploads, plaes make sure to create form.py file in your project.


class BlogPostForm(form.ModelForm):
      class Meta:
      model = BlogPost
      fields = ['BlogImage',' Writer','BlogTitle','BlogContent','Slug']

Upvotes: 0

Related Questions