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)
