2010-09-20 37 views
5

Tôi là một người mới đến django, vì vậy câu hỏi có thể là câm, nhưng xin vui lòng dạy tôi đúng cách nếu bạn biết điều đó. Tôi đã cố gắng giải quyết vấn đề, nhưng tôi vẫn thua lỗ. Dưới đây là vấn đề của tôi:Hai phím nước ngoài và một giá trị trong mẫu django

Tôi có một lớp trong mô hình của tôi có hai phím nước ngoài:

class X(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Y(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Z(models.Model): 
    name = models.CharField(max_length=30) 
    x = models.ForeignKey(X) 
    y = models.ForeignKey(Y) 
    def __unicode__(self): 
     return name 

Theo quan điểm của tôi, tôi nhận được một phần danh sách các đối tượng X và một phần danh sách các đối tượng Y như vậy:

def MyView(x_pattern, y_pattern): 
    x_list = X.objects.filter(name__contains=x_pattern) 
    y_list = Y.objects.filter(name__contains=y_pattern) 
    z_list = Z.objects.all() 
    return render_to_response({'x_list': x_list, 'y_list': y_list, 'z_list': z_list}) 

Trong mẫu của tôi, tôi muốn để có thể hiển thị một bảng như sau:

<table> 
    <tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
    </tr> 
    {% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td> 
     <!-- here I need help: 
      I need to display z[x, y] if it exists, or "N/A" otherwise. 
     --> 
    </td> 
    {% endfor %} 
    </tr> 
    {% endfor %} 

Làm cách nào để làm điều này đúng trong django?

Cảm ơn bạn rất nhiều,

Trả lời

0

Bạn nên giữ logic trong chế độ xem của mình. Tại sao bạn không chỉ lọc z_list ở đó?

z_list = Z.objects.filter(x__name__contains=x_pattern, y__name__contains=y_pattern) 
+0

Tôi có thể lọc danh sách trong chế độ xem, nhưng nó vẫn không giúp tôi hiển thị chính xác (nghĩa là tôi cần ghép cặp khóa (x, y) thành giá trị z [x, y] trong mẫu để hiển thị nó trong một ô bảng thích hợp). Am i thiếu cái gì ở đây? – mfynf

1

Là @DZPM suggested, bạn nên nghĩ đến việc giữ logic trong chế độ xem của mình. [cừu] Tôi đã từng phát minh ra cấu trúc dữ liệu "Bảng" của riêng mình để làm điều gì đó rất giống nhau. Bảng có các hàng tương ứng với X, các cột tương ứng với Y và các ô tương ứng với Z[X, Y]. Sau đó tôi đã viết các bộ lọc get_rowget_cell để thực hiện thủ thuật trong mẫu. [/ sheepish]

Điều đó nói rằng, những gì bạn muốn có thể được thực hiện bằng cách sử dụng một cặp bộ lọc tùy chỉnh. Giải pháp này khá tiết kiệm.

@register.filter 
def x_is(value, x): 
    return value.x == x 

@register.filter 
def y_is(value, y): 
    return value.y == y 

Bạn có thể sử dụng các bộ lọc trong các mẫu như hình dưới đây:

{% if z|x_is:x and z|y_is:y %} 
    {{ z }} 
{% else %} 
    N/A 
{% endif %} 
+0

Bingo! Cảm ơn bạn rất nhiều - đó là liên kết còn thiếu (bộ lọc tùy chỉnh). – mfynf

0

cách tiếp cận khác là để tạo ra một máy phát điện theo quan điểm của bạn, và sau đó gửi nó cho mẫu của bạn bối cảnh:

# nested inside your view function 
def x_and_z_list(y): 
    for x in x_list: 
     z_obj = x.z_set.filter(y=y) 
     z_name = z_obj or 'N/A' 
     yield {'x': x, 'z': z_name} 
return render_to_response('mytemplate', {'list_generator': x_and_z_list} 

Sau đó mẫu của bạn có thể trông như thế này:

{% for y in y_list %} 
    <tr> 
     <td>{{ y }}</td> 
     {% for pair in list_generator.y %} {# pair is the dict you yielded before #} 
      <td>{{ pair.x.name }}: {{ pair.z }}</td> 
     {% endfor %} 
    </tr> 
{% endfor %} 
0

Tôi kết hợp các khái niệm về bộ lọc và chức năng tùy chỉnh làm đối tượng lớp đầu tiên tạo bộ lọc mẫu thành một hàm functor (đối tượng hàm).

Đây là những gì tôi đã kết thúc thực hiện:

def z_filter(x, y): 
    z_list = list(Z.objects.filter(x, y)) 
    return z_list.pop().name or 'N/A' 
register.filter(z_filter) 

Trong mẫu:

{% load z_filter %} 
<table> 
<tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
</tr> 
{% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td>{{ x|z_filter:y }}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
</table> 

Cảm ơn tất cả mọi người đã giúp đỡ!

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