Chỉ cập nhật các trường cụ thể trong một mô hình.


92

Tôi có một người mẫu

class Survey(models.Model):
    created_by = models.ForeignKey(User)
    question = models.CharField(max_length=150)
    active = models.NullBooleanField()
    def __unicode__(self):
        return self.question

và bây giờ tôi chỉ muốn cập nhật activelĩnh vực này. Vì vậy, tôi làm điều này:

survey = get_object_or_404(Survey, created_by=request.user, pk=question_id)
survey.active = True
survey.save(["active"]) 

Bây giờ tôi nhận được một lỗi IntegrityError: PRIMARY KEY must be unique.

Tôi có đúng với phương pháp này để cập nhật không?

Câu trả lời:


186

Để cập nhật một tập hợp con các trường, bạn có thể sử dụng update_fields:

survey.save(update_fields=["active"]) 

Đối update_fieldssố đã được thêm vào Django 1.5. Trong các phiên bản trước đó, bạn có thể sử dụng update()phương pháp thay thế:

Survey.objects.filter(pk=survey.pk).update(active=True)

17

Thông thường, cách chính xác để cập nhật các trường nhất định trong một hoặc nhiều trường hợp mô hình là sử dụng update()phương pháp trên bộ truy vấn tương ứng. Sau đó, bạn làm một cái gì đó như thế này:

affected_surveys = Survey.objects.filter(
    # restrict your queryset by whatever fits you
    # ...
    ).update(active=True)

Bằng cách này, bạn không cần phải gọi save()trên mô hình của mình nữa vì mô hình được lưu tự động. Ngoài ra, update()phương pháp trả về số lượng bản khảo sát đã bị ảnh hưởng bởi bản cập nhật của bạn.


2
Cảm ơn. Tôi đã thử nó với .getthay vì .filtervà điều này không hoạt động. Nhưng với bộ lọc, nó hoạt động tốt. Bạn có biết điều gì sai với mã của tôi ở trên không?
Người dùng đã đăng ký

Vấn đề của bạn có thể liên quan đến question_id. Giá trị này đến từ đâu? Và dòng chính xác nào nâng cao IntegrityError?
pemistahl 16/12/12

question_idđến từ các url (?P<question_id>\d+). Lỗi của tôi là trên máy chủ đang hoạt động django 1.4 được cài đặt và mã của tôi là 1.5. Nhưng với mã của bạn, nó hoạt động tốt.
Người dùng đã đăng ký

2
@RegisteredUser, có vẻ như không có phương thức "cập nhật" trên các đối tượng, chỉ trên các tập truy vấn. Khi bạn sử dụng .filter (), bạn nhận được một bộ truy vấn (chứa không hoặc nhiều đối tượng) trở lại. Khi bạn sử dụng .get (), bạn nhận được một đối tượng duy nhất.
mgojohn

Theo mặc định, gọi save()(giải pháp @Alasdair) là một giải pháp an toàn hơn, vì phương pháp này có thể kích hoạt những thứ như xác thực hoặc bất kỳ mã tùy chỉnh nào hơn là update()không.
David D.
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.