Django: When the table structure is one-to-many, add data to report IntegrityError

Briefly describe the project logic
Problem explanation:
My table relationship is: Books (each book has only one publisher)-Publish (each publisher publishes multiple books), which is a one-to-many relationship.
The data table is created as follows models.py:

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, unique=True)
    city = models.CharField(max_length=32)
    email = models.EmailField()


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)
    headImg = models.ImageField(upload_to='', null=True)
    # 与Publish建立一对多的关系,外键字段建立在多的一方,字段publish如果是外键字段,那么它自动是int类型
    publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)  # foreignkey里面可以加很多的参数
    # to指向表,to_field指向你关联的字段,不写这个,默认会自动关联主键字段,on_delete级联删除
    # 字段名称不需要写成publish_id,orm在翻译foreignkey的时候会自动给你这个字段拼上一个_id,这个字段名称在数据库里面就自动变成了publish_id

Web page book.html:
Insert picture description here
still return to the current page.
Insert picture description here
Completed background logic: view.py

Problem phenomenon one:

Insert picture description here
IntegrityError at /books/(1048, "Column'publish_id' cannot be null")
tells you that the'publish_id' column cannot be empty. When books add new data, the publisher should already exist when the publisher information is added.
Therefore, it is usually necessary to create the "one" form first, and then fill in the "more" form.

The solution is as follows:

Fill in the data in the publish table first, and then pass the found record to the publish field that books need to fill in the form.
Insert picture description here

Problem phenomenon two

Insert picture description here
When creating a one-to-many table relationship, the default ispublish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)

Insert picture description here

Correct way of writing:

    def post(self, request):
        publish_obj = models.Publish.objects.update_or_create(name=request.POST.get("book_pub"))
        books_obj = models.Book.objects.update_or_create(
            title=request.POST.get("book_name"),
            price=request.POST.get("book_price"),
            publishDate=request.POST.get("book_pubT"),
            headImg=request.POST.get("book_face"),
            publish=models.Publish.objects.get(name=request.POST.get("book_pub"))
        )
        return render(request, "try-on/books.html",
                      {
    
    "ok_msg": "提交成功!",
                       }
                      )

The second modification method:
Because the Book table is stored in the database, the structure:
Insert picture description here
Therefore, in the logic, you can directly assign a value to publish_id, and publish_id stores the id value of the corresponding field of Publish.

    def post(self, request):
        publish_obj = models.Publish.objects.update_or_create(name=request.POST.get("book_pub"))
        books_obj = models.Book.objects.update_or_create(
            title=request.POST.get("book_name"),
            price=request.POST.get("book_price"),
            publishDate=request.POST.get("book_pubT"),
            headImg=request.POST.get("book_face"),
            publish_id=6
        )
        return render(request, "try-on/books.html",
                      {
    
    "ok_msg": "提交成功!",
                       }
                      )

to sum up

  1. To build a model relationship, usually the only side of the many-to-one relationship is written into the multi-model as an attribute field.
    Insert picture description here
  2. When writing logic to increase table data, write "one" first. Add the data in the "multi" table.

Guess you like

Origin blog.csdn.net/beauthy/article/details/113256578