2010-01-25 25 views
5

Tôi đang cố gắng tạo trang tiểu sử hiển thị số lượng người lùn được chỉ định cho từng nghề nghiệp tương ứng. Tôi có 4 nghề nghiệp, 2 công việc trong mỗi nghề nghiệp đó và dĩ nhiên nhiều người lùn từng có một công việc. Làm cách nào tôi có thể đếm số lượng người lùn trong mỗi nghề nghiệp đó? Giải pháp của tôi là đưa các tên nghề nghiệp vào HTML và tạo một truy vấn cho mỗi nghề nghiệp nhưng điều đó có vẻ giống như một lượng truy vấn quá mức.Django: Nhiều COUNT từ hai mô hình cách nhau

Dưới đây là những gì tôi "muốn" để xem:

Unassigned: 3 
Construction: 2 
Farming: 0 
Gathering: 1 

Dưới đây là mô hình của tôi. Tôi thêm một số phức tạp bằng cách không kết nối nghề nghiệp trực tiếp với mô hình Người lùn của tôi (họ đã kết nối với công việc của họ).

from django.contrib.auth.models import User 
from django.db import models 

class Career(models.Model): 
    name = models.CharField(max_length = 64) 

    def __unicode__(self): 
     return self.name 

class Job(models.Model): 
    career = models.ForeignKey(Career) 
    name = models.CharField(max_length = 64) 
    career_increment = models.DecimalField(max_digits = 4, decimal_places = 2) 
    job_increment = models.DecimalField(max_digits = 4, decimal_places = 2) 

    def __unicode__(self): 
     return self.name 

class Dwarf(models.Model): 
    job = models.ForeignKey(Job) 
    user = models.ForeignKey(User) 
    created = models.DateTimeField(auto_now_add = True) 
    modified = models.DateTimeField(auto_now = True) 
    name = models.CharField(max_length = 64) 

    class Meta: 
     verbose_name_plural = 'dwarves' 

    def __unicode__(self): 
     return self.name 

EDIT 1 quan điểm của tôi trông giống như sau:

def fortress(request): 
    careers = Career.objects.annotate(Count('dwarf_set')) 
    return render_to_response('ragna_base/fortress.html', {'careers': careers}) 

và mẫu:

{% for career in careers %} 
    <li>{{ career.dwarf_set__count }}</li> 
{% endfor %} 

Lỗi này là:

Cannot resolve keyword 'dwarf_set' into field. Choices are: id, job, name 

SOLUTION

xem:

def fortress(request): 
    careers = Career.objects.all().annotate(dwarfs_in_career = Count('job__dwarf')) 
    return render_to_response('ragna_base/fortress.html', {'careers': careers}) 

mẫu:

{% for career in careers reversed %} 
    <li>{{ career.name }}: {{ career.dwarves_in_career }}</li> 
{% endfor %} 

Thậm chí tốt hơn SOLUTION

careers = Career.objects.filter(Q(job__dwarf__user = 1) | Q(job__dwarf__user__isnull = True)) \ 
    .annotate(dwarves_in_career = Count('job__dwarf')) 

Đừng quên from django.db.models import Count, Q

Những gì tôi thích về giải pháp trên là nó không chỉ trả về sự nghiệp mà người lùn đang làm việc mà ngay cả những nghề nghiệp không có vấn đề tiếp theo tôi gặp phải. Dưới đây là quan điểm của tôi về tính đầy đủ:

<ul> 
{% for career in careers %} 
    <li>{{ career.name }}: {{ career.dwarves_in_career }}</li> 
{% endfor %} 
</ul> 

Trả lời

1

Điều này có làm những gì bạn muốn không?

from django.db.models import Count 
Career.objects.annotate(Count('dwarf')) 

Bây giờ mỗi đối tượng career nên có một tài sản dwarf__count.

+0

Không tệ! Tôi tiếp tục nhận được lỗi: Không thể giải quyết từ khóa 'dwarf_set' vào trường. Các lựa chọn là: id, job, name Nhưng tôi đang thử những thứ khác nhau. – TheLizardKing

+0

Tôi cảm thấy điều này sẽ hoạt động nếu mô hình Lùn của tôi liên quan trực tiếp đến mô hình Hướng nghiệp của tôi nhưng tôi đã chọn kết nối hai thông qua mô hình Công việc của mình để cho phép thay đổi nghề nghiệp. – TheLizardKing

1

Bạn không thể chỉ đếm được nhóm theo sự nghiệp? Và làm một tham gia bên ngoài nếu bạn cần các hàng không trả về quá.

2

ORM của Django sẽ không khiến việc này trở nên đơn giản hơn. Cách đơn giản là để làm một cái gì đó như:

cho sự nghiệp trong Career.objects.all():. career.dwarf_set.all() đếm()

Đó sẽ thực hiện 1 truy vấn cho từng công việc (O (n) phức tạp).

Bạn có thể thử tăng tốc bằng cách sử dụng Django's Aggregation feature, nhưng tôi không hoàn toàn chắc chắn nếu nó sẽ làm những gì bạn cần. Bạn sẽ phải xem xét.

Tùy chọn thứ ba là sử dụng SQL tùy chỉnh, điều này hoàn toàn sẽ hoàn thành công việc. Bạn chỉ cần viết nó và duy trì nó khi ứng dụng của bạn phát triển và thay đổi ...

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