Как собрать файл изображения и сохранить его в базе данных
Это проект, который собирает данные для ввода имени, цены и изображения.
Основная проблема, с которой я сталкиваюсь, заключается в размещении изображения из фронтенда (html) в бэкенд (базу данных).
Вот мои коды, в чем проблема
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"),
]
Изображения не сохраняются в базе данных. Они сохраняются в каком-то хранилище, а путь хранится в базе данных. Я вижу, что вы не указали путь к полю изображения, там должно быть что-то вроде параметра upload_to.
примерно так:
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"}))
При приеме файлов из форм, наряду с request.POST, необходимо также получить request.FILES...
form = ProductCreationForm(request.POST, request.FILES)
Кстати, create(name=name, price=price, image=image) уже сохранил элемент, поэтому нет необходимости вызывать метод save new_item.save().
Вместо этого было бы проще просто работать с model form. Поэтому я просто обновляю ваш код здесь...
models.py файл:
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 файл:
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',
)
Затем внутри вашего представления в файле views.py:
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')
Наконец, атрибут action не нужен на вашем form tag, поэтому вы можете удалить его, поскольку тот же function будет обрабатывать post request.
Дополнительно убедитесь, что в вашем файле setting.py установлено что-то для MEDIA_URL и MEDIA_ROOT
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
В файле urls.py вашего проекта:
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)