Как собрать файл изображения и сохранить его в базе данных

Это проект, который собирает данные для ввода имени, цены и изображения.

Основная проблема, с которой я сталкиваюсь, заключается в размещении изображения из фронтенда (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)
Вернуться на верх