Поле обновления в БД в django из представлений с существующей формой, не будет обновляться из-за «Ошибки целостности»

#python #django

#python #django

Вопрос:

Мой первый пост, действительно новичок в программировании. У меня возникли проблемы с обновлением поля в форме. Я постараюсь объяснить все, что в моих силах. У меня есть класс каталога (продукты или услуги) с парой полей, 2 из них должны быть уникальными.

models.py

 class Catalogo(models.Model):
    item = models.CharField(
        max_length=100, help_text="Product or service name", unique=True
    )
    sku = models.CharField(max_length=50, help_text="Part Number", unique=True)
    category = models.CharField(
        max_length=15, choices=categoria, verbose_name="Category"
    )
    description = models.CharField(
        max_length=200,
        help_text="Item description",
        verbose_name="Descripción",
    )
    created = models.DateTimeField(auto_now_add=True, help_text="Created")
    updated = models.DateTimeField(auto_now_add=True, help_text="Updated")
    active = models.BooleanField(default=True)

    class Meta:
        verbose_name = "product and service"
        verbose_name_plural = "products and services"

    def __str__(self):
        return self.item
 

Тогда у меня есть форма для сбора информации

forms.py

 
categories = [("Product", "Product"), ("Service", "Service")]

class NewProductForm(forms.Form):

    item = forms.CharField(
        widget=forms.TextInput(attrs={"class": "form-control"}),
        label="Item",
        max_length=100,
    )
    sku = forms.CharField(
        widget=forms.TextInput(attrs={"class": "form-control"}),
        label="Part number",
        max_length=50,
    )
    category = forms.ChoiceField(
        choices=categories,
        label="Category",
    )
    description = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control"}),
        label="Item description",
    )
 

Теперь для представлений … я создал 2 функции: одну для добавления нового продукта / услуги и одну для обновления

views.py

 
def new_prod_serv(request):
    new_form = NewProductForm()
    if request.method == "POST":
        new_form = NewProductForm(request.POST)

        if new_form.is_valid():
            new_product = Catalogo(
                item=new_form["item"].value(),
                sku=new_form["sku"].value(),
                category=new_form["category"].value(),
                description=new_form["description"].value(),
            )
            new_product.save()
            return redirect("products-services")

        else:
            print(new_form.errors)

    context = {"formulario": new_form}

    return render(request, "SkytechnosaApp/comercial/nuevoproducto.html", context)



def update_prod_serv(request, primarykey):
    product_service = Catalogo.objects.get(id=primarykey)
    item = product_service.item
    sku = product_service.sku
    category = product_service.category
    description = product_service.description
    form_data = {
        "item": item,
        "sku": sku,
        "category": category,
        "description": description,
    }
    form = NewProductForm(initial=form_data)
    if request.method == "POST":
        form = NewProductForm(request.POST, initial=form_data)

        if form.is_valid():
            form.save()
            return redirect("products-services")

        else:
            print(form.errors)

    context = {"form": form}

    return render(request, "SkytechnosaApp/comercial/nuevoproducto.html", context)
 

HTML работает нормально, проблема, с которой я сталкиваюсь, заключается в том, что я нажимаю на edit…it заполнит форму информацией о продукте или услуге, которую я хочу отредактировать (это нормально), но затем я вношу изменения, например, в поле комментария (просто хочу обновить комментарий) изатем я получаю ошибку IntegrityError в / comercial / productos / nuevo
Сбой УНИКАЛЬНОГО ограничения: Comercial_catalogo.sku

Это похоже на попытку создать другой продукт, потому что, когда я возвращаюсь, редактирую все поля и нажимаю сохранить, я вижу, что создан другой продукт, но я просто хотел обновить, а не создавать новый продукт….чего мне не хватает?

Спасибо!

Ответ №1:

Ваш код формы, который вы вставили в свой вопрос, не завершен (это просто form.Form не a form.ModelForm , и все же вы позвонили form.save() )

forms.py

 class NewProductForm(forms.ModelForm):

    item = forms.CharField(
        widget=forms.TextInput(attrs={"class": "form-control"}),
        label="Item",
        max_length=100,
    )
    sku = forms.CharField(
        widget=forms.TextInput(attrs={"class": "form-control"}),
        label="Part number",
        max_length=50,
    )
    category = forms.ChoiceField(
        choices=categories,
        label="Category",
    )
    description = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control"}),
        label="Item description",
    )
    
    class Meta:
        model = Catalogo

 

После этого, если вы хотите обновить экземпляр (вместо его создания), вы должны сообщить ModelForm, какой экземпляр он должен обновить:

view.py

 def update_prod_serv(request, primarykey):
    ...
    instance = Catalogo.objects.get(id=primarykey)
    if request.method == 'POST':
        form = NewProductForm(request.POST, instance=instance) # you don't need to use `initial` since 
        if form.is_valid():
            form.save()
    ...

 

Тем не менее, обычно лучше иметь только ОДНО представление для создания и обновления. Если вы хотите посмотреть, как это работает, дайте мне знать.

Комментарии:

1. Спасибо за ваш ответ Grand Phuba, поэтому лучше использовать ModelForm, а не form для передачи экземпляра… я постараюсь и дам вам знать

2. Это работало как charme wifn modelform … большое спасибо, Великий Фуба