Невозможно присвоить "id": "Product.category" должен быть экземпляром "CategoryProduct".

я работаю над проектом django и у меня возникла эта ошибка (Cannot assign "'11'": "Product.category" должен быть экземпляром "CategoryProduct".) кто-нибудь может мне помочь, пожалуйста.

Модель:

class Product(models.Model):
    name = models.CharField("Nombre", max_length=150)
    category = models.ForeignKey(CategoryProduct, on_delete=models.SET_NULL, null=True, related_name='category')  

    def __str__(self):
        return self.name

Вид:

class ProductCreateView(CreateView):
model = Product
form_class = ProductForm
success_url = '/adminpanel/products/'

def post(self, request, *args, **kwargs):
    form = self.get_form()
    category = CategoryProduct.objects.get(id=request.POST['category'])
    
    if form.is_valid():
        product = form.save(commit=False)
        product.category = category
        product.save()

Форма:

class ProductForm(forms.ModelForm):
    name = forms.CharField(max_length=150, label="Nombre")
    category = forms.ChoiceField(choices=[(obj.id, obj.name) for obj in CategoryProduct.objects.all()], label="Categoría")

class Meta:
    model = Product
    fields = ['name', 'category']

Вы можете позволить Django ModelForm сделать свою работу, это создаст ModelChoiceField [Django-doc], где система застревает: она пытается присвоить первичный ключ category, но это должен быть объект ProductCategory, так что вы можете позволить Django обработать это с помощью:

class ProductForm(forms.ModelForm):

    class Meta:
        model = Product
        fields = ['name', 'category']

If you want to specify a different label, you can use the verbose_name=… [Django-doc] from the model field, or specify this in the labels options [Django-doc] of the Meta of the ProductForm. So you can specify Categoria with:

class Product(models.Model):
    name = models.CharField('Nombre', max_length=150)
    category = models.ForeignKey(
        CategoryProduct,
        on_delete=models.SET_NULL,
        null=True,
        related_name='products',
        verbose_name='Categoria'
    )

    def __str__(self):
        return self.name

тогда CreateView может просто использовать свою шаблонную логику:

class ProductCreateView(CreateView):
    model = Product
    form_class = ProductForm
    success_url = '/adminpanel/products/'

Note: The related_name=… parameter [Django-doc] is the name of the relation in reverse, so from the Category model to the Product model in this case. Therefore it (often) makes not much sense to name it the same as the forward relation. You thus might want to consider renaming the category relation to products.

Вернуться на верх