2011-06-22 31 views
5

Vì vậy, tôi có một tập hợp các công việc mà có thể xuất hiện trong nhiều chủng loại:đếm Complex qua nhiều đối với nhiều lĩnh vực trong Django ORM

class TaskGroup(models.Model): 
    name = models.CharField(max_length=200) 
    slug = models.SlugField(max_length=200) 
    icon = models.CharField(max_length=200, blank=True, null=True) 

    def __unicode__(self): 
     return unicode(self.name) 


class Task(models.Model): 
    start_date = models.DateField() 
    end_date = models.DateField() 
    is_date_fuzzy = models.BooleanField() 
    name = models.CharField(max_length=200) 
    assignee = models.ForeignKey(User, verbose_name="users who is assigned the task", blank=True, null=True) 
    task_groups = models.ManyToManyField(TaskGroup) 

Như bạn có thể thấy, mỗi nhiệm vụ có thể xuất hiện trong nhiều nhóm nhiệm vụ.

Tôi muốn các điều kiện sau được thỏa mãn bởi truy vấn của tôi:

  1. Các danh sách tất cả TaskGroups nên trả lại.
  2. Số lượng công việc trong một nhóm cụ thể. I E. đồ nội thất (3), Bộ đồ giường (2), Tầng đèn (6)
  3. Nếu không có nhiệm vụ cho một TaskGroup cụ , cho biết nhóm nên có 0
  4. Nhiệm vụ trong mỗi nhóm được giới hạn bởi người dùng hiện tại.

Điều tốt nhất tôi đã đưa ra cho đến nay là một cái gì đó như thế này:

TaskGroup.objects.filter(
    task__assignee=current_usr 
).annotate(
    task_count=Count('task__id') 
).order_by('name') 

Nhưng nó lọc tất cả mọi thứ trước khi thực hiện đếm, vì vậy tôi không thấy nhóm nhiệm vụ với zero nhiệm vụ.

Có lẽ tôi đang rất suy nghĩ nhưng tôi đã cố gắng để làm điều này cho các lứa tuổi và tôi ở giai đoạn này chỉ cám dỗ để lặp lại và làm đếm mình.

Tôi thực sự hy vọng bạn có thể giúp tiết kiệm phần còn lại của sự tỉnh táo của tôi!

Trả lời

0

Tôi gặp vấn đề tương tự một lần. Một giải pháp sẽ là sử dụng truy vấn con phụ:

TaskGroup.objects.extra(
    select={"task_count": "SELECT COUNT(*) from app_task where app_task.id=app_taskgroup.task_id AND app_task.assignee = '?'"}, 
    select_params = [current_usr] 
).order_by('name') 

Hoặc điều gì đó tương tự. Có lẽ khóa tham gia là sai.

Nhưng điều này thật xấu xí. và phá vỡ rất nhiều DRY và DB độc lập priciples.

Tùy chọn tốt hơn có thể là sử dụng 2 truy vấn. Nhóm thứ hai cho các Nhóm cụ thể không có bất kỳ nhiệm vụ nào được giao cho người dùng đó:

empty_groups = TaskGroup.objects.exclude(task__assignee=current_usr) 

Sau đó, chỉ lặp lại hai tập hợp thay vì chỉ một bộ.

+0

Cảm ơn, tôi có thể sẽ chỉ sử dụng SQL thô được bao bọc trong một lớp Trình quản lý mở rộng. Khá bực bội khi thấy đây là một cas sử dụng rất rõ ràng. Có lẽ tôi có thể làm điều đó theo cách thứ hai; hai truy vấn có thể tách biệt vì tôi không cần chúng là một phần của cùng một danh sách - có lẽ tốt hơn là nên sử dụng các Nhóm tác vụ không sử dụng trong danh sách khác (tôi vẫn cần mọi người có thể nhìn thấy chúng). Cảm ơn bạn đã chỉnh sửa câu hỏi của tôi - Tôi thích một chút tính gọn gàng của OCD. – pip

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