2010-03-20 35 views
5

Tôi đang chuyển từ nền PHP sang phát triển Django qua python, chủ yếu để giải quyết MVC (hoặc MVT) mà tôi cảm thấy có ý nghĩa nhất, mặc dù trong mẫu này Tôi đã bắt đầu chú ý nhiều mã lặp lại trong quan điểm của mình. Ví dụ, khi đăng nhập, tôi có thông tin về người dùng mà tôi muốn xuất hiện trên mọi trang, mặc dù khi sử dụng render_to_response và trong mỗi chế độ xem này, tôi phải lấy thông tin và chuyển nó đến hàm render_to_response .Django - Mẹo để tránh lặp lại mã trong giao diện

Tôi tự hỏi điều gì sẽ là cách hiệu quả nhất để cắt giảm mã trùng lặp mà thực chất là bắt buộc trong tất cả các chế độ xem trong một ứng dụng cụ thể.

Xin cảm ơn trước.

Trả lời

4

Cá nhân tôi là một fan hâm mộ lớn của trang trí, đó là một tính năng python mà không phải là cụ thể cho Django. Trang trí là đường cú pháp hoàn hảo ở trên các hàm bậc cao và chúng đặc biệt hữu ích trong việc giảm boilerplate trong khung nhìn - bạn có thể nhanh chóng xác định hàm bao bọc tổng quát, trong đó bạn có thể đặt mã lặp lại để dễ dàng sử dụng lại và thuận tiện -chuyển đổi liên tục.

Có thể dễ dàng cho bạn thấy hơn là giải thích cách hoạt động của chúng. Dưới đây là một cái nhìn ví dụ đơn giản:

def listpage(request): 
    return HttpResponse(render_to_string("itemlist.html", { 
     "items": Item.objects.filter(visible=True).order_by("-modifydate") 
    })) 

def itemlist_tags(request, tags): 
    return HttpResponse(render_to_string("itemlist.html", { 
     "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"), 
    })) 

... nhưng sau đó nói rằng bạn muốn tạo ra các trang này yêu cầu người dùng đăng nhập Bạn có thể thêm mã đăng nhập như sau:.

def listpage(request): 
    if not request.user.is_authenticated(): 
     return f(request, *args, **kwargs) 
    else: 
     return HttpResponse(render_to_string("itemlist.html", { 
      "items": Item.objects.filter(visible=True).order_by("-modifydate") 
     })) 

def itemlist_tags(request, tags): 
    if not request.user.is_authenticated(): 
     return f(request, *args, **kwargs) 
    else: 
     return HttpResponse(render_to_string("itemlist.html", { 
      "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"), 
     })) 

.. đang bắt đầu nhận được sự chú ý lớn hơn và lặp đi lặp lại, ngay cả đối với một ví dụ giả tạo. Bạn có thể thực hiện chức năng của mình mỏng lại với trang trí, như vậy:

từ trang trí nhập khẩu trang trí

@decorator 
def loginrequired(f, request, *args, **kwargs): 
    if request.user.is_authenticated(): 
     return f(request, *args, **kwargs) 
    else: 
     return HttpResponseRedirect("/") 

@loginrequired 
def listpage(request): 
    return HttpResponse(render_to_string("itemlist.html", { 
     "items": Item.objects.filter(visible=True).order_by("-modifydate") 
    })) 

    @loginrequired 
def itemlist_tags(request, tags): 
    return HttpResponse(render_to_string("itemlist.html", { 
     "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"), 
    })) 

@loginrequired 
def another_such_function(request): 
    (...) 

@loginrequired 
def and_again(request): 
    (...) 

gì sẽ xảy ra là chức năng trang trí được thực hiện tại thời điểm xác định của hàm. Chữ 'f' trong ví dụ của tôi là một đối tượng biểu diễn hàm mà trình trang trí được áp dụng cho, mà bạn có thể thao tác theo những cách bất tận.

Điều này yêu cầu số decorator library, miễn phí trên PyPI là nhiều mảnh ghép trăn tốt, bạn sẽ tìm thấy.

Bạn không cần thư viện này để viết chức năng trang trí, nhưng nó rất hữu ích, đặc biệt là ở đầu. Họ có thể làm nhiều hơn thế nữa - bất kì người gọi nào cũng có thể là người trang trí; bạn có thể trang trí các phương thức lớp và chặn biến số self; trang trí có thể được xích lên, như vậy:

@second 
@first 
def originalfunction(*args): 
    (...) 

tôi sẽ rời khỏi thăm dò về những gì bạn có thể làm với ví dụ chức năng dễ dàng bậc cao manpipulation cho bạn, khái niệm này nên kích thích sự thèm ăn của bạn. Tôi có nhiều ví dụ hơn là tốt, cho bạn hoặc bất kỳ người hâm mộ python mới tò mò khác. Chúc may mắn.

+1

Nhân tiện, hàm 'được gắn thẻ()' trong chế độ xem giả thứ hai không phải là lỗi đánh máy; đó là một giao diện đơn giản mà tôi đã viết cho ứng dụng gắn thẻ django, cũng trong tên của bản sửa lỗi soạn thảo, mà cái tò mò sẽ tìm thấy ở đây: http://www.djangosnippets.org/snippets/1942/ – fish2000

+0

Rất hữu ích, cảm ơn, trang trí dường như có nhiều công dụng hơn cho tôi. – neopickaze

5

Đóng gói mã chung trong một hàm và gọi nó từ các chế độ xem khác nhau. Nghe có vẻ tầm thường, nhưng đó là giải pháp cho 99% nhu cầu đó.

Để có câu trả lời cụ thể hơn, bạn sẽ phải hiển thị ví dụ cụ thể hơn về mã bạn muốn chạy.

5

Có hai cách chính để trừu tượng hóa nội dung chung.

Context processors là cách tốt nhất để truyền bit dữ liệu mà bạn biết bạn sẽ cần trên mọi chế độ xem.

Template tags - thẻ bao gồm đặc biệt - rất hữu ích để hiển thị các khu vực riêng biệt của trang sẽ giống nhau trên một số mẫu.

3

Ngoài ra, đừng quên khoảng generic views! Trong 90% các trường hợp, bạn có thể bọc object_list hoặc object_detail và lưu lại một số mã.

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