具有基于 Class 的视图的 Django 内联表单集

Django inline formsets with Class-based view

我正在尝试做基于 Django class 的 CreateView 内联表单集。 我有一个产品模型和一个 productImage 模型,并且 productImage 是内联的 一切看起来都很好,但在我提交我的产品后,selected 格式集中的图像将不会保存。 这是我的代码

models.py:

     class Product(models.Model):
        name=models.CharField(max_length=200, db_index=True),
        slug=models.SlugField(max_length=200, db_index=True, allow_unicode=True),
        description=models.TextField(blank=True),
        vector_column=SearchVectorField(null=True, editable=False),
        meta={"indexes": (GinIndex(fields=["vector_column"]),)}
        category = models.ForeignKey(Category, related_name='products', 
                   on_delete=models.CASCADE)
        price = models.DecimalField(max_digits=10, decimal_places=2)
        available = models.BooleanField(default=True)

        def get_absolute_url(self):
            return reverse('shop:product_detail', args=[self.id, self.slug])
        
     class ProductImage(models.Model):
        product = models.ForeignKey(Product, default=None, on_delete=models.CASCADE)
        image = models.ImageField(upload_to='products/%y/%m/%d')

        def __str__(self):
             return self.product.name

views.py

class ProductCreate(StaffAccessMixin, ProductFormValidMixin, ProductFieldsMixin,
                 CreateView):
model = Product

def get_context_data(self, **kwargs):
    context = super(ProductCreate, self).get_context_data(**kwargs)
    if self.request.POST:
        context['product_image_formset'] = ProductImageFormset(self.request.POST)
    else:
        context['product_image_formset'] = ProductImageFormset()
    return context


template_name = 'products/product-create-update.html'

ProductFormValidMixin:

class ProductFormValidMixin():
  def form_valid(self, form):
    context = self.get_context_data()
    product_image_formset = context['product_image_formset']
    if self.request.user.is_superuser:
        self.obj = form.save()
        if product_image_formset.is_valid():
            product_image_formset.instance = self.obj
            product_image_formset.save()
        return redirect('administration:product-update', pk=self.obj.pk)
    else:
        self.obj = form.save(commit=False)
        self.obj.available = False
    return super().form_valid(form)

ProductFieldsMixin:

class ProductFieldsMixin():
  def dispatch(self, request, *args, **kwargs):
    if request.user.is_superuser:
        self.fields = ["name",
                       "slug",
                       "description",
                       "category",
                       "price",
                       "available",
                       "image",
                       ]
    else:
        raise Http404
    return super().dispatch(request, *args, **kwargs)

forms.py:

from django.forms.models import inlineformset_factory
from .models import Product, ProductImage

ProductImageFormset = inlineformset_factory(Product, ProductImage, fields=('image',), 
extra=3)

表单集模板:

<h5 class="text-info">Add Product Metas</h5>
 {{ product_image_formset.management_form|crispy }}

  {% for form in product_image_formset.forms %}
       <tr class="{% cycle 'row1' 'row2' %} formset_row-{{product_image_formset.prefix }}">
         {% for field in form.visible_fields %}
                <td>
                    {# Include the hidden fields in the form #}
                     {% if forloop.first %}
                           {% for hidden in form.hidden_fields %}
                                 {{ hidden }}
                           {% endfor %}
                     {% endif %}
                     {{ field.errors.as_ul }}
                     {{ field|as_crispy_field }}
               </td>
          {% endfor %}
     </tr>
  {% endfor %}

一切正常,我的产品表单在提交后已保存,但我 select 在我的表单集中的图像不会保存

问题已解决!

此代码适用于其他类型的数据,但不适用于图像和文件 解决这个问题 get_context_data 函数应该是这样的:

def get_context_data(self, **kwargs):
    context = super(ProductCreate, self).get_context_data(**kwargs)
    if self.request.POST:
    context['product_image_formset']=ProductImageFormset(self.request.POST,
                                                         **self.request.FILES**)
    else:
        context['product_image_formset'] = ProductImageFormset()
    return context

在我的第一个代码中 self.request.FILES 丢失了 :) 因此无法保存图像