Cách chính xác để sử dụng get_or_create?


203

Tôi đang cố gắng sử dụng get_or_create cho một số trường trong biểu mẫu của mình, nhưng tôi gặp lỗi 500 khi cố gắng làm như vậy.

Một trong những dòng trông như thế này:

customer.source = Source.objects.get_or_create(name="Website")

Lỗi tôi nhận được cho đoạn mã trên là:

Cannot assign "(<Source: Website>, False)": "Customer.source" 
   must be a "Source" instance.

Câu trả lời:


353

Từ tài liệu get_or_create :

# get_or_create() a person with similar first names.

p, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

# get_or_create() didn't have to create an object.
>>> created
False

Giải thích: Các lĩnh vực được đánh giá cho sự tương đồng, phải được đề cập bên ngoài defaults. Phần còn lại của các lĩnh vực phải được bao gồm trong defaults. Trong trường hợp sự kiện CREATE xảy ra, tất cả các trường được xem xét.

Có vẻ như bạn cần quay trở lại một tuple, thay vì một biến duy nhất, hãy làm như thế này:

customer.source,created = Source.objects.get_or_create(name="Website")

3
FYI được tạo ra là một boolean. Đúng nếu được tạo, Sai nếu được tải xuống
Josh

3
Một bổ sung save()là dư thừa?
zypro

@zypro Giống như create(), tạo đối tượng và lưu tất cả trong một bước và không cần bất kỳsave()
Amin Mir

32

get_or_create trả lại một tuple.

customer.source, created = Source.objects.get_or_create(name="Website")

16
Hoặc, nếu bạn không quan tâm đến cờ boolean:customer.source = Source.objects.get_or_create(name="Website")[0]
mipadi

7
@mipadi Tôi thích hơn customer.source, _ = Source.objects.get_or_create(name="Website"), vì nó làm cho thực tế là một tuple được trả lại rõ ràng hơn, giúp tránh các lỗi trong tương lai.
Solomon Ucko

15

get_or_create() trả về một tuple:

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created có giá trị boolean, được tạo hay không.

  • customer.source có một đối tượngget_or_create() phương thức.


12

Theo câu trả lời @Tobu và bình luận @mipadi, theo cách dễ hiểu hơn, nếu không quan tâm đến cờ đã tạo, tôi sẽ sử dụng:

customer.source, _ = Source.objects.get_or_create(name="Website")

4

Vấn đề bạn đang gặp phải là một tính năng được ghi lại của get_or_create .

Khi sử dụng các đối số từ khóa khác với "mặc định", giá trị trả về get_or_createlà một thể hiện. Đó là lý do tại sao nó hiển thị cho bạn các giá trị trong giá trị trả về.

bạn đã có thể sử dụng customer.source = Source.objects.get_or_create(name="Website")[0] để có được giá trị chính xác.

Đây là một liên kết cho tài liệu: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.