首页 > 解决方案 > Django:如何使用外键字段集编辑页面(无法编辑和发布到模型)

问题描述

我正在尝试通过 html 表单编辑 django 数据库。但是我不确定为什么会出现以下错误。产品类别是外键,我无法更改它的值。我该如何解决这个错误?谢谢你。

/shop/polyester-cushions/eiffel/edit_product/ 处的 ValueError 无法分配“'Polyester Cushions'”:“Product.category”必须是“Category”实例。

模型.py

from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User

class Category(models.Model):
    name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to='category', blank=True)

    def __str__(self):
        return '{}'.format(self.name)

class Product(models.Model):    
    CATEGORY_CHOICES = (
        ("Cotton Cushions", "Cotton Cushions"),
        ("Polyester Cushions", "Polyester Cushions")
    )
    name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, choices=CATEGORY_CHOICES)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return '{}'.format(self.name)

编辑产品.html

<div class="form-group row">
    <label class="col-sm-2 col-form-label">Category</label>
        <div class="col-sm-10">
            <select name="category" class="form-control" value="{{ product.category }}">
            <option {% if product.category == "Cotton Cushions" %} selected {% endif %} value="Cotton Cushions">Cotton Cushions</option>
            <option {% if product.category == "Polyester Cushions" %} selected {% endif %} value="Polyester Cushions">Polyester Cushions</option>
            </select>
        </div>
</div>

视图.py

@login_required(login_url="/")
def EditProduct(request, c_slug, product_slug):
    try:
        product = Product.objects.get(category__slug=c_slug, slug=product_slug)
        error = ''
        if request.method == 'POST':
            product_form = ProductForm(request.POST, request.FILES, instance=product)
            if product_form.is_valid():
                product.save()
                return redirect('shop/my_products.html/')
            else:
                error = "Data is not valid"

        return render(request, 'shop/edit_product.html', {'product':product, 'error':error})
    except Product.DoesNotExist:
        return redirect('/')

表格.py

from django import forms
from django.forms import ModelForm
from .models import Product

class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ('name','slug','description','category','price','image','stock','available')

标签: pythonhtmldjangotemplates

解决方案


试试下面的代码:

通常html是这样的:

<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="ok">
</form>

models.py(您可能需要运行 makemigrations 和 migrate)

from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User

class Category(models.Model):
    CATEGORY_CHOICES = (
        ("Cotton Cushions", "Cotton Cushions"),
        ("Polyester Cushions", "Polyester Cushions")
    )
    name = models.CharField(max_length=250, unique=True, choices=CATEGORY_CHOICES)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to='category', blank=True)

    def __str__(self):
        return self.name

class Product(models.Model):    
    name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return self.name

views.py(或者你可以使用 django 的 UpdateView)

@login_required(login_url="/")
def EditProduct(request, c_slug, product_slug):
    try:
        product = Product.objects.get(category__slug=c_slug, slug=product_slug)
    except Product.DoesNotExist:
        return redirect('/')
    if request.method == 'POST':
        form = ProductForm(request.POST, request.FILES, instance=product)
        if form.is_valid():
            form.save()
            return redirect('shop/my_products.html')
    else:
        form = ProductForm(instance=product)
    return render(request, 'shop/edit_product.html', {'form': form})

推荐阅读