2012-05-03 25 views
5

tôi đã tuyên bố queryset dài này trên một cái nhìnRe đánh giá truy vấn django sau khi thay đổi làm cho cơ sở dữ liệu

contributions = user_profile.contributions_chosen.all()\ 
    .filter(payed=False).filter(belongs_to=concert)\ 
    .filter(contribution_def__left__gt=0)\ 
    .filter(contribution_def__type_of='ticket') 

mà tôi sử dụng trong mẫu của tôi

context['contributions'] = contributions 

Và sau này xem mà tôi thực hiện thay đổi (thêm hoặc loại bỏ một bản ghi) vào bảng contributions_chosen và nếu tôi muốn ngữ cảnh của tôi ['đóng góp'] cập nhật tôi cần phải requery cơ sở dữ liệu với cùng một truy vấn lenghty.

contributions = user_profile.contributions_chosen.all()\ 
.filter(payed=False).filter(belongs_to=concert)\ 
.filter(contribution_def__left__gt=0)\ 
.filter(contribution_def__type_of='ticket') 

Và sau đó một lần nữa cập nhật bối cảnh của tôi

context['contributions'] = contributions 

Vì vậy, tôi đã tự hỏi nếu theres bất kỳ cách nào tôi có thể tránh lặp lại bản thân tôi, phải đánh giá lại những đóng góp để nó thực sự phản ánh các dữ liệu thực tế trên cơ sở dữ liệu. Lý tưởng nhất là tôi sẽ sửa đổi các đóng góp queryset và giá trị của nó sẽ được cập nhật, và đồng thời cơ sở dữ liệu sẽ phản ánh những thay đổi này, nhưng tôi không biết làm thế nào để làm điều này.

UPDATE: Đây là những gì tôi làm giữa bối cảnh hai [ 'đóng góp'] = đóng góp

tôi thêm một đối tượng đóng góp mới cho contributions_chosen (đây là một mối quan hệ M2M),

contribution = Contribution.objects.create(kwarg=something,kwarg2=somethingelse) 
user_profile.contributions_chosen.add(contribution) 
contribution.save() 
user_profile.save() 

Và trong một số trường hợp, tôi xóa đối tượng đóng góp đóng góp = user_profile.contributions_chosen.get (id = 1) user_profile.contributions_chosen.get (id = request.POST ['con Contributions.delete()

Như bạn có thể thấy tôi đang sửa đổi tables_chosen vì vậy tôi phải phát hành lại truy vấn và cập nhật ngữ cảnh. Tôi đang làm gì sai?

CẬP NHẬT Sau khi nhìn thấy ý kiến ​​của bạn về đánh giá, tôi nhận ra tôi làm eval queryset tôi làm len (đóng góp) giữa ngữ cảnh ['đóng góp'] và điều đó có vẻ là vấn đề. Tôi sẽ chỉ di chuyển nó sau khi hoạt động cơ sở dữ liệu và thats nó, nhờ anh chàng.

+0

Có vẻ bạn chưa đánh giá queryset 'contributions', do đó không cần phải lo lắng về việc cập nhật nó bởi vì nó vẫn có dữ liệu không được tải xuống DB. 'QuerySet' được đánh giá lười biếng do đó nó không có gì liên quan đến các hàng DB cho đến khi được đánh giá. – okm

Trả lời

2

Tôi không biết làm thế nào bạn có thể tránh đánh giá lại truy vấn, nhưng một cách để lưu một số câu lệnh lặp lại trong mã của bạn là tạo một dict với tất cả các bộ lọc đó và chỉ định filter args làm dict:

query_args = dict(
    payed=False, 
    belongs_to=concert, 
    contribution_def__left__gt=0, 
    contribution_def__type_of='ticket', 
) 

và sau đó

contributions = user_profile.contributions_chosen.filter(**query_args) 

này chỉ loại bỏ một số mã lặp đi lặp lại, nhưng không giải quyết được câu hỏi lặp đi lặp lại. Nếu bạn cần phải thay đổi args, chỉ cần xử lý query_args như một dict Python bình thường, nó là một bản cập nhật sau khi tất cả :)

+1

Trong mã, ông cung cấp cho anh ta dường như không đánh giá truy vấn. Truy vấn được đánh giá khi ông lặp trên nó trong mẫu hoặc khi anh ấy làm những thứ khác mà gây nên đánh giá truy vấn, như ghi nhận tại https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets -là-đánh giá –

3

Có vẻ bạn chưa đánh giá queryset contributions, do đó không cần phải lo lắng về cập nhật nó vì nó vẫn chưa tìm nạp dữ liệu từ DB.

Bạn có thể gửi mã giữa hai context['contributions'] = contributions dòng? Thông thường trước khi bạn đánh giá queryset contributions (ví dụ bằng cách duyệt qua nó hoặc gọi __len__() của nó), nó không chứa bất cứ điều gì đọc từ DB, do đó bạn không cần phải cập nhật nội dung của nó.

Để đánh giá lại một queryset, bạn có thể

# make a clone 
contribution._clone() 
# or any op that makes clone, for example 
contribution.filter() 

# or clear its cache 
contribution._result_cache = None 

# you could even directly add new item to contribution._result_cache, 
# but its could cause unexpected behavior w/o carefulness 
+1

Cũng 'contribution.all() ' –

+0

Các tài liệu đặc biệt [đề nghị sử dụng' tất cả() '] (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#all) vì mục đích này. –

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