2008-10-31 32 views
8

Làm cách nào để tạo truy vấn cho phép nối ngoài hoàn toàn trên một nhãn quan M2M bằng cách sử dụng API truy vấn django?Tham gia đầy đủ bên ngoài trong django

Điều này không được hỗ trợ, một số gợi ý về cách tạo người quản lý của riêng tôi để thực hiện việc này sẽ được hoan nghênh.

Đã chỉnh sửa để thêm: @ S.Lott: Cảm ơn bạn đã khai sáng. Sự cần thiết cho OUTER JOIN xuất phát từ ứng dụng. Nó phải tạo ra một báo cáo cho thấy dữ liệu được nhập vào, ngay cả khi nó vẫn chưa hoàn thành. Tôi không biết thực tế là kết quả sẽ là một lớp/mô hình mới. Gợi ý của bạn sẽ giúp tôi khá nhiều.

Trả lời

11

Django không hỗ trợ "tham gia" theo nghĩa SQL thông thường - nó hỗ trợ điều hướng đối tượng.

Lưu ý rằng liên kết quan hệ (bên trong hoặc bên ngoài) tạo ra một "lớp" mới của các thực thể. Một trong đó không có một định nghĩa trong Django. Vì vậy, không có "bộ kết quả" phù hợp vì không có định nghĩa lớp cho những thứ bạn quay lại. Điều tốt nhất bạn có thể làm là xác định một bộ dữ liệu sẽ được đóng gói với Không có đối với các kết hợp bị thiếu.

Kết nối bên ngoài (hoặc phải) bên trái trông như thế này. Nó tạo ra hai tập con rời rạc, những người có một tập hợp các thực thể liên quan và những người không có liên quan.

for obj in Model1.objects.all(): 
    if obj.model2_set().count() == 0: 
     # process (obj, None) -- no Model2 association 
    else: 
     for obj2 in obj.model2_set.all(): 
      # process (obj, obj2) -- the "inner join" result 

Kết nối bên ngoài "Đầy đủ" là sự kết hợp của các mục còn lại không có mối quan hệ.

for obj2 in Model2.objects.all(): 
    if obj2.model1_set().count() == 0: 
     # process (None, obj2) -- no Model1 association 

Vấn đề luôn là, bạn đang xử lý bộ sưu tập lạ này của ba tập con khác nhau của đối tượng?

Điểm của cơ sở dữ liệu đối tượng là tập trung xử lý đối tượng và đối tượng liên kết của nó.

Bộ sưu tập đặc biệt được gọi là "tham gia quan hệ" không bao giờ có trong mô hình đối tượng ban đầu. Đó là một lớp đối tượng mới được xây dựng từ hai (hoặc nhiều hơn) đối tượng gốc.

Tồi tệ hơn, kết nối bên ngoài tạo bộ sưu tập với nhiều lớp con (nối bên trong, nối ngoài bên trái và nối ngoài bên phải). Bộ sưu tập của những thứ gì có nghĩa là?

Đợi đã, điều đó có thể tồi tệ hơn. Nếu quá trình xử lý bao gồm các kiểm tra cho các thuộc tính còn thiếu (tức là if someObj.anObj2attribute is None: chúng tôi đang tìm kiếm Model1 các mục không có đối tượng liên quan. tại sao không chỉ làm các truy vấn riêng biệt quá trình amd mỗi tập con đúng


Edit:?.. Khi bạn đang hiển thị "không đầy đủ" trạng thái, nó không phải là một bên ngoài-tham gia ở tất cả đó là đơn giản hơn nhiều bạn cần phải tạo một (hoặc hai) bộ sưu tập riêng biệt trong chức năng xem của bạn để mẫu của bạn hiển thị.

Trước tiên, bạn nên sử dụng mã trạng thái, chứ không phải sự hiện diện hoặc abse nce của một khóa ngoại. Các khóa ngoại lệ tùy chọn không có "lý do" - chúng có ở đó hay không. Mã trạng thái có thể cung cấp các sắc thái có ý nghĩa hữu ích ("không đầy đủ", "lỗi", "bị hỏng", "không áp dụng", "bị xóa", v.v.)

errorList1 = Model1.objects.filter(status="Incomplete") 
errorList2 = Model2.objects.filter(status="Incomplete") 

Đây là hai phần không tham gia của một kết hợp bên ngoài hoàn toàn. Sau đó, bạn có thể hiển thị hai danh sách lỗi này trong mẫu của mình với các tiêu đề cột và mã trạng thái thích hợp và mọi thứ.

Bạn thậm chí có thể đặt chúng vào một bảng duy nhất để bắt chước bên ngoài đầy đủ tuổi tham gia dân báo cáo sử dụng để xem

<table> 
    <tr><th>Model1</th><th>Model2</th></tr> 
    {% for e1 in errorList1 %} 
    <tr><td>e1</td><td>NULL</td></tr> 
    {% endfor %} 
    {% for e2 in errorList2 %} 
    <tr><td>NULL</td><td>e2</td></tr> 
    {% endfor %} 
</table> 

Trông giống như một bên ngoài đầy đủ tham gia báo cáo. Nếu không có sự tham gia đầy đủ bên ngoài.

+0

Bạn nói đúng. Tôi sẽ viết một khung nhìn tính toán bảng cần thiết cho "FULL OUTER JOIN" của tôi trong python và sau đó đưa kết quả đó vào mẫu để render. Cảm ơn. – Ber

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