เหตุใดจึงต้องสร้าง create_foo () ในรุ่น Django ผู้จัดการแทนการสร้าง ()


10

การอ่านเอกสาร Django ขอแนะนำให้สร้างวิธีการสร้างที่กำหนดเองสำหรับแบบจำลองที่มีชื่อFooโดยกำหนดไว้create_fooในตัวจัดการ:

class BookManager(models.Manager):
    def create_book(self, title):
        book = self.create(title=title)
        # do something with the book
        return book

class Book(models.Model):
    title = models.CharField(max_length=100)

    objects = BookManager()

book = Book.objects.create_book("Pride and Prejudice")

คำถามของฉันคือทำไมก่อนหน้านี้ชอบที่จะเอาชนะcreateวิธีการของชั้นฐาน:

class BookManager(models.Manager):
    def create(self, title):
        book = self.model(title=title)
        # do something with the book
        book.save()
        return book

class Book(models.Model):
    title = models.CharField(max_length=100)

    objects = BookManager()

book = Book.objects.create("Pride and Prejudice")

Imo ดูเหมือนว่าการเอาชนะเท่านั้นที่createจะป้องกันไม่ให้ใครใช้โดยไม่ได้ตั้งใจเพื่อสร้างอินสแตนซ์โมเดลที่มีรูปแบบcreate_fooไม่ถูกต้องเนื่องจากสามารถข้ามได้โดยสมบูรณ์:

class BookManager(models.Manager):
    def create_book(self, title):
        book = self.create(title=title, should_not_be_set_manually="critical text")
        return book

class Book(models.Model):
    title = models.CharField(max_length=100)
    should_not_be_set_manually = models.CharField(max_length=100)

    objects = BookManager()

# Can make an illformed Book!!
book = Book.objects.create(title="Some title", should_not_be_set_manually="bad value")

มีข้อได้เปรียบอะไรบ้างในการทำเช่นเดียวกับที่เอกสารแนะนำหรือที่จริงแล้วการเอาชนะนั้นcreateดีกว่าอย่างเป็นกลาง?

คำตอบ:


10

ใช่แน่นอนคุณสามารถทำได้ แต่ถ้าคุณดูตัวอย่างที่คุณอ้างจากเอกสารมันไม่ได้เกี่ยวกับว่าคุณควรจะสร้างทับหรือไม่มันเกี่ยวกับ

อย่างไรก็ตามหากคุณทำเช่นนั้นโปรดอย่าเปลี่ยนลายเซ็นการโทรเนื่องจากการเปลี่ยนแปลงใด ๆ อาจทำให้อินสแตนซ์โมเดลไม่ได้รับการบันทึก

รักษาลายเซ็นโทร เนื่องจากอินเทอร์เฟซที่มีให้สำหรับคุณอาจถูกใช้โดย django ภายใน หากคุณปรับเปลี่ยนสิ่งต่าง ๆ อาจไม่ทำลายสำหรับคุณ แต่สำหรับ Django

ในตัวอย่างนี้พวกเขาไม่ได้แนะนำสิ่งนี้createแต่เป็นตัวสร้างโมเดล

ประการที่สองอินเทอร์เฟซมาตรฐานสำหรับcreateการรับอาร์กิวเมนต์ของคำหลักเท่านั้น

def create(self, **kwargs):

แต่ถ้าคุณปรับเปลี่ยนเพื่อให้มีการโต้แย้งตำแหน่งdef create(self, title):มันจะแตกในที่ที่มันถูกใช้ใน Django หรือด้วยวิธีมาตรฐาน ดังนั้นคุณควรขยายฟังก์ชั่นที่มีอยู่เดิมไม่ได้ปรับเปลี่ยนและส่วนใหญ่อาจทำลายได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.