This is a project that collects inputs for name, price and image.
The major problem I am encountering is posting an image from my frontend(html) to the backend(database).
These are my codes, what is the issue
models.py
from django.db import models
from datetime import datetime
class Product(models.Model):
name = models.CharField(max_length=250)
price = models.FloatField(default=0)
image = models.ImageField()
forms.py
from django import forms
class ProductCreationForm(forms.Form):
name = forms.CharField(label="Product Name", max_length=250, required=True)
price = forms.DecimalField(label="Price", required=True, initial=0)
image = forms.ImageField(label="Image", required=True, widget=forms.FileInput(attrs={'accept': "image/x-png, image/jpeg"}))
views.py
def product_create(request):
form = ProductCreationForm()
if request.method == "POST":
form = ProductCreationForm(request.POST)
if form.is_valid():
name = form.cleaned_data["name"]
price = form.cleaned_data["price"]
image = form.cleaned_data["image"]
new_item = Product.objects.create(name=name, price=price, image=image)
new_item.save()
return redirect('shelf')
else:
return render(request, "workbench/product_create.html", {"form": form})
create.html
<form action="", method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" >submit</button>
</form>
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.shelf, name="shelf"),
path('/create', views.product_create, name="product-create"),
]
CodePudding user response:
Images are not saved in the database. they save in some storage and the path is stored in the database. I see you have not set any path to your imagefield , there should be something called the upload_to parameter.
something like this:
from django import form
class ProductCreationForm(forms.Form):
name = forms.CharField(label="Product Name", max_length=250, required=True)
price = forms.DecimalField(label="Price", required=True, initial=0)
image = forms.ImageField(upload_to="projectimg/",label="Image", required=True, widget=forms.FileInput(attrs={'accept': "image/x-png, image/jpeg"}))
CodePudding user response:
When accepting files from forms, along with request.POST
, you should also fetch request.FILES
as well...
form = ProductCreationForm(request.POST, request.FILES)
By the way, the create(name=name, price=price, image=image)
already saved the item so there's no need to call the save
method new_item.save()
.
It would be easier to just work with a model form
instead. So I'm just updating your code here...
models.py
file:
class Product(models.Model):
name = models.CharField(max_length=250)
price = models.FloatField(default=0)
image = models.ImageField(upload_to='image_uploads/', null=True, blank=True)
forms.py
file:
from .models import Product
from django import forms
from django.utils.translation import gettext_lazy as _
class ProductCreationForm(forms.ModelForm):
class Meta:
model = Product
fields = "__all__"
labels = {
"name": _("Product Name"),
"price": _("Price"),
"image": _("Image"),
}
required = (
'name',
'price',
'image',
)
Then within your view in the views.py
file:
if request.method == "POST":
form = ProductCreationForm(request.POST, request.FILES)
if form.is_valid():
form.save() # This here will save the necessary data to the database
else:
print(form.errors) # To show you what field(s) are causing the form not to submit
return redirect('shelf')
Finally, the action
attribute is not needed on your form
tag
, so you can remove it since the same function
will be handling the post request
.
Additionally, ensure that in your setting.py
file you have something set for the MEDIA_URL
and the MEDIA_ROOT
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
In your project's urls.py
file:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
...
]
if settings.DEBUG:
urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)