Home > Net >  Image not getting uploaded in Django
Image not getting uploaded in Django

Time:01-31

I tried to save a record using two different methods but both are not working.

  1. Django Form
  2. Models (create method)

1 I have created a ModelForm


class ProductForm(ModelForm):
    class Meta:
        model= ProductDetails
        fields= ("name","category","subcategory","price","mrp","product_details","main_img","img1","img2","img3")

        labels={
            "name":"Product Name",
            "product_details":"Description",
            "category":"Category",
            "subcategory":"Sub-Category",
            "price":"Price",
            "mrp":"MRP",
            "main_img":"Main Image",
            "img1":"Image 1",
            "img2":"Image 2",
            "img3":"Image 3",
        }

        widgets = {
            'name':forms.TextInput(attrs={'class':'form-control validate',}),
            'product_details':forms.TextInput(attrs={'class':'form-control validate',}),

            'category':forms.TextInput(attrs={'class':'custom-select tm-select-accounts',}),
            'subcategory':forms.TextInput(attrs={'class':'custom-select tm-select-accounts',}),

            'price':forms.TextInput(attrs={'class':'form-control validate',}),
            'mrp':forms.TextInput(attrs={'class':'form-control validate',}),

            'main_img':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
            'img1':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
            'img2':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
            'img3':forms.FileInput(attrs={'class':'btn btn-primary btn-block mx-auto',}),
            
        }

Models File


# For Product details
class ProductDetails(models.Model):
    name= models.CharField(max_length=100)
    price= models.FloatField()
    mrp= models.FloatField()
    main_img = models.ImageField(upload_to='product_img')
    img1 = models.ImageField(upload_to='product_img')
    img2 = models.ImageField(upload_to='product_img')
    img3 = models.ImageField(upload_to='product_img')
    category = models.ForeignKey(Category, related_name='produits', on_delete=models.CASCADE)
    subcategory = models.ForeignKey(SubCategory, related_name='produits', on_delete=models.CASCADE)
    product_details = RichTextField(blank=True, null=True)
    trending = models.BooleanField(default=False)
    
    def __str__(self):
        return self.name

Method 1

Save record using form.save() getting Form validation error I have tried by removing main_img,img1,img2,img3 from all place (Forms.py, template, views,py). Then there is not validation error and record is getting saved successfully.

The validation error is just because of some issue with the image uploading

print(form.errors)= <ul ><li>main_img<ul ><li>This field is required.</li></ul></li><li>img1<ul ><li>This field is required.</li></ul></li><li>img2<ul ><li>This field is required.</li></ul></li><li>img3<ul ><li>This field is required.</li></ul></li></ul>


def add_product(request):
    if request.method == "POST":
        form = ProductForm(request.POST or None, request.FILES or None)
        print(form.errors )
        if form.is_valid():
            category_id = request.POST.get('category')
            subcategory_id = request.POST.get('subcategory')
            category= Category.objects.get(id=int(category_id))
            subcategory= SubCategory.objects.get(id=int(subcategory_id))
            form.category = category
            form.subcategory = subcategory
            form.save()
            return redirect("/dashboard/products")
    form = ProductForm()
    categories=Category.objects.all()
    subcategories=SubCategory.objects.all()
    return render(request, "01-add-product.html", "form":form,"categories":categories,"subcategories":subcategories})

Method 2

Tried Saving records using models.save() The record is getting saved but image is not getting uploaded to the media folder On saving record from Django-admin the image is getting uploaded to proper place i.e. /media.product_img/... But From this outside HTML its showing the file name in Django-admin but the file is not available in media folder

I already added urlpattern static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) in my project/urls.py. Also tried adding the same in urls.py of this app

Note = I have mentioned upload_to=product_img in my model (this may be important to know)

def add_product(request):
    if request.method == "POST":        
        name = request.POST['name']
        product_details = request.POST['product_details']
        category_id = request.POST.get('category')
        subcategory_id = request.POST.get('subcategory')
        category= Category.objects.get(id=int(category_id))
        subcategory= SubCategory.objects.get(id=int(subcategory_id))
        price = request.POST['price']
        mrp = request.POST['mrp']
        main_img = request.POST['main_img']
        img1 = request.POST['img1']
        img2 = request.POST['img2']
        img3 = request.POST['img3']
        product = ProductDetails.objects.create(name=name,product_details=product_details,category=category,subcategory=subcategory,price=price,mrp=mrp,main_img=main_img,img1=img1,img2=img2,img3=img3)
        product.save()

Here is my template

{% extends '01-admin-base.html' %}
{% load static %}
{% block content %}

    <div >
      <div >
        <div >
          <div >
            <div >
              <div >
                <h2 >Add Product</h2>
              </div>
            </div>
            <div >
              <div >
                <form action="" method="post" >
                  {% csrf_token %}
                  {{form.media}}
                  <div >
                    <label
                      for="name"
                      >Product Name
                    </label>
                    {{form.name}}
                    
                  </div>
                  
                  <div >
                    <label
                      for="category"
                      >Category</label
                    >
                    <select
                      
                      id="category" name="category"
                    >
                      <option selected>Select category</option>
                      {% for category in categories %}
                      <option value="{{category.id}}">{{category.name}}</option>
                      {% endfor %}
                    </select>
                  </div>
                  <div >
                    <label
                      for="subcategory"
                      >Sub Category</label
                    >
                    <select
                      
                      id="subcategory" name="subcategory"
                    >
                      <option selected>Select sub-category</option>
                      {% for subcategory in subcategories %}
                      <option value="{{subcategory.id}}">{{subcategory.name}}</option>
                      {% endfor %}
                    </select>
                  </div>
                  <div >
                      <div >
                          <label
                            for="price"
                            >Price
                          </label>
                          {{form.price}}
                        </div>
                        <div >
                          <label
                            for="mrp"
                            >MRP
                          </label>
                          {{form.mrp}}
                        </div>
                  </div>
                  <div >
                    <label
                      for="description"
                      >Description</label
                    >
                    {{form.product_details}}
                  </div>
                  
              </div>
              
              <div >
                <div >
                  <label>Main Image</label>
                  {{form.main_img}}
                </div>
                <br><br>
                <label>Images</label>
                <div >
                  {{form.img1}}                  
                </div>
                <div >
                  {{form.img2}}                  
                </div>
                <div >
                  {{form.img3}}                  
                </div>
              </div>

              <div >
                <button type="submit" >Add Product Now</button>
              </div>
            </form>
            </div>
          </div>
        </div>
      </div>
    </div>

{% endblock content %}

Please help me to get solution for this.

CodePudding user response:

You need to add enctype="multipart/form-data"> in Html form so:

<form action="/" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
      <label for="fname">First name:</label>
      <input type="text" id="fname" name="fname"><br><br>
      <label for="lname">Last name:</label>
      <input type="text" id="lname" name="lname"><br><br>
      <input type="submit" value="Submit">
 </form>
  • Related