2012-03-15 28 views
5

Có thể hoặc tôi có nên thực hiện điều này trong chế độ xem không?Thay đổi đối tượng QuerySet khi đang bay ở Django

a = SomeTable.objects.all() 
for r in a: 
    if r.some_column == 'foo': 
     r.some_column = 'bar' 

Nó hoạt động như một nhà vô địch, nhưng tôi đã thử một điều tương tự ở một nơi khác và tôi nhận được kết quả lạ, ngụ ý rằng các đối tượng QuerySet không thích bị xáo trộn. Và, tôi không thấy bất cứ điều gì trong các tài liệu tốt hay xấu cho loại lừa này.

Tôi biết có những cách khác để làm điều này, nhưng tôi đặc biệt muốn biết nếu đây là một ý tưởng tồi, tại sao nó xấu, và nếu nó thực sự là xấu, những gì 'tốt nhất' nhất django/pythonic cách để thay đổi giá trị trên bay sẽ được.

Trả lời

6

Điều này là tốt miễn là bạn không làm bất cứ điều gì sau đó sẽ khiến cho bộ truy vấn được đánh giá lại - ví dụ, cắt nó. Điều đó sẽ thực hiện một truy vấn khác đến cơ sở dữ liệu và tất cả các đối tượng đã sửa đổi của bạn sẽ được thay thế bằng các đối tượng mới.

Một cách để tự bảo vệ mình chống lại điều đó sẽ được chuyển đổi vào một danh sách đầu tiên:

a = list(SomeTable.objects.all()) 

Bằng cách này, cắt thêm vv sẽ không gây ra một cuộc gọi db tươi, và bất kỳ sửa đổi sẽ được giữ lại.

+0

Cảm ơn, Daniel. Ví dụ của bạn là chính xác những gì tôi có nghĩa là khi tôi nói "Tôi biết có những cách khác để làm điều này", và tôi đánh giá cao làm rõ của bạn, quá. Oh, và ví dụ của bạn về việc lấy một lát là chính xác những gì đã gây ra những kết quả lạ tôi đã đề cập. Tôi hơi xấu hổ vì tôi không hiểu điều đó, và tôi rất vui vì bạn đã chỉ ra điều đó. Chúc mừng! – proffrink

0

Yup. Xem tài liệu here

SomeTable.objects.filter(some_column='foo').update(some_column='bar') 

Tôi sẽ đi với thành ngữ của Django. Nó thực hiện câu lệnh SQL với một câu lệnh duy nhất với 'where' và 'update' thay vì gửi nhiều câu lệnh SQL như mã của bạn. Điều này tiết kiệm thời gian. Kiểm tra với 'connection' của Django để kiểm tra thời gian SQL.

+4

Cảm ơn và tôi xin lỗi nếu tôi không rõ ràng, nhưng tôi không quan tâm đến việc cập nhật cơ sở dữ liệu, chỉ cần sửa đổi đầu ra cho mục đích hiển thị. – proffrink

Các vấn đề liên quan