Saif Khan
Saif Khan

Reputation: 484

Django ModelForm not saving data to database, Form.save is not working?

Hello I am django beginner having tough time could someone please help me I don't know what am I doing wrong ? I am trying to create a form and saving some data through it by using form.save(). And I am new to here also so don't mind any mistakes.

Here is my model:

from django.db import models
from stores.models import Store


class Category(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name


class Product(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=30)
    price = models.DecimalField(max_digits=5, decimal_places=5)
    image = models.ImageField(upload_to='upload_to/')
    category = models.ForeignKey(Category, default='Default', on_delete=models.CASCADE, blank=False, null=False)
    store = models.ForeignKey(Store, on_delete=models.CASCADE, blank=False, null=False)

Here is my view:

from django.shortcuts import render, redirect
from .forms import NewPro


def pro(request):

    if request.method == 'POST':
        form = NewPro(request.POST)
        if form.is_valid():
            form.save()
            return redirect('stores_list')

    else:
        form = NewPro()

    return render(request, "default/add_product.html", {'form': form})


def product_list(request):
    return render(request, 'default/product_list.html')

Here is my form:

from django import forms
from .models import Product


class NewPro(forms.ModelForm):
    class Meta:
        model = Product
        fields = ('name', 'price', 'image','category', 'store',)

default/add_product.html :

{% extends 'default/base.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
    <h1>Add Product details</h1>
    <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Add Product</button>
    </form>{% endblock %}
 </html>

Settings.py settings

MEDIA_ROOT = '/home/saifi/Saif_project/final_project/MEDIA_ROOT/upload_to'

Upvotes: 2

Views: 8514

Answers (3)

Youssef BH
Youssef BH

Reputation: 582

You forgot request.FILES in your pro view function, you have an image file after all.

def pro(request):

    if request.method == 'POST':
        form = NewPro(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('stores_list')

    else:
        form = NewPro()

    return render(request, "default/add_product.html", {'form': form})

Try using the form this way:

<form action="YOUR_URL_HERE" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Add Product</button>
</form>

I hope this will help. Welcome aboard ;)

Upvotes: 1

Siddanatham Saikalyan
Siddanatham Saikalyan

Reputation: 81

Your indentation is wrong, the else should be for first 'if'

def pro(request):
  form = NewPro()
  if request.method == 'POST':
    form = NewPro(request.POST)
    if form.is_valid():
      form.save()
      return redirect('stores_list')

  else:
    form = NewPro()
  return render(request, "default/add_product.html", {'form': form})

Upvotes: 1

Jason Havenaar
Jason Havenaar

Reputation: 151

I can see some indentation issues in the view - but I'll guess that's just formatting when copying into Stackoverflow.

the form.is_valid() check will validate all your form fields and will only write to the database if all the input fields are valid. If it's not saving, the first place I'd check would be for form errors.

In your template you can render the errors with {{form.errors}} and it will list each field and error.

Upvotes: 4

Related Questions