2010-01-14 34 views
13

Bối cảnh:Django Apps nên gói phương tiện tĩnh như thế nào?

Tôi bắt đầu sử dụng Django lần đầu tiên, cũng là bước đột phá đầu tiên của tôi vào phát triển web. Tôi chỉ bị mắc kẹt trên toàn bộ "phục vụ phương tiện truyền thông tĩnh" vấn đề. Sau khi dành một chút thời gian xem tất cả các tài liệu và câu hỏi StackOverflow, tôi nghĩ rằng tôi hiểu cách hoạt động của nó (ví dụ: MEDIA_ROOT, MEDIA_URL, đang cập nhật tệp url, v.v.).

My Câu hỏi:

Ok, vì vậy đây là phần tôi không chắc chắn về. Ứng dụng Django được cho là "có thể cắm được", tức là tôi có thể di chuyển một ứng dụng từ dự án này sang dự án khác. Vì vậy, làm thế nào các ứng dụng này nên gói phương tiện truyền thông tĩnh?

Ví dụ: giả sử tôi có ứng dụng "foo", trong đó có các mẫu tải một số tệp css/hình ảnh. Tôi phải đặt những tệp này ở đâu, để chúng tự động được phân phối khi tôi đưa ứng dụng vào?

Giải pháp duy nhất tôi thấy, là cài đặt một ứng dụng phải bao gồm bước bổ sung sao chép phương tiện tĩnh của nó tới một số nơi trên máy chủ của riêng bạn phục vụ phương tiện đó.

Đây có phải là cách được chấp nhận để làm điều đó không? Nó bao gồm một bước bổ sung, nhưng có lẽ đó là tiêu chuẩn khi giao dịch với web-dev (tôi mới nên tôi không thực sự biết).

Ngoài ra, nếu đây là cách, có cách nào tiêu chuẩn để thu thập tất cả các phương tiện truyền thông tĩnh của tôi để làm cho nó dễ dàng để biết những gì tôi cần phải phục vụ? (Tức là, nó có tiêu chuẩn để có một thư mục có tên là "media" hay cái gì đó bên trong ứng dụng không?).

Cảm ơn,

Trả lời

9

ước là đưa phương tiện truyền thông tĩnh trong cả hai phương tiện truyền thông/appname/hoặc tĩnh/appname/trong ứng dụng (tương tự như mẫu).

Để sử dụng các ứng dụng trong dự án đi kèm với phương tiện, tôi khuyên bạn nên sử dụng django-staticfiles. Nó sẽ tự động phục vụ media (bao gồm media trong ứng dụng) trong quá trình phát triển thông qua một view thay thế django.views.static.serve, và nó đi kèm với lệnh quản lý build_static sẽ sao chép media từ tất cả các ứng dụng vào một thư mục duy nhất để phục vụ trong sản xuất.

Cập nhật: django-staticfiles có become part of Django 1.3. Nó bây giờ hy vọng phương tiện truyền thông ứng dụng để sống trong một thư mục con "tĩnh /" của ứng dụng, không phải là "phương tiện truyền thông /". Và lệnh quản lý bây giờ là "tập thể".

+0

Đây là cách tiếp cận chính xác, như của Django 1.3. –

+1

Lưu ý rằng https://github.com/jaddison/django-cachebuster/ cung cấp thẻ {% static%} rất hữu ích cho Django 1.3 – Eli

2

Ứng dụng duy nhất tôi biết rằng đề với điều này mà không cần bất kỳ sự can thiệp là khá tuyệt vời django-debug-toolbar, mặc dù nó là đáng tranh cãi rằng đây không phải là một ví dụ tuyệt vời, vì nó là một ứng dụng được thiết kế đặc biệt cho chế độ gỡ lỗi chỉ có.

Cách nó thỏa thuận với nó là nó phục vụ phương tiện truyền thông của mình thông qua Django bản thân - xem nguồn cho urls.py:

url(r'^%s/m/(.*)$' % _PREFIX, 'debug_toolbar.views.debug_media'), 

Nói chung, đây là một ý tưởng tồi (bạn không muốn để phục vụ tĩnh tệp qua Django), mỗi this comment from the documentation:

[Cung cấp tệp tĩnh qua Django] không hiệu quả và không an toàn. Không sử dụng thiết bị này trong cài đặt sản xuất . Sử dụng tùy chọn này chỉ để phát triển .

Rõ ràng, thanh công cụ gỡ lỗi django chỉ được sử dụng để phát triển, vì vậy tôi nghĩ phương pháp triển khai của nó có ý nghĩa, nhưng điều này là rất nhiều ngoại lệ.

Nói chung, cách tốt nhất mà tôi biết để làm là tạo liên kết tượng trưng bất cứ nơi nào phương tiện của bạn được lưu trữ vào phương tiện bên trong mã ứng dụng của bạn. Ví dụ: tạo thư mục có tên là media trong ứng dụng của bạn và sau đó yêu cầu người dùng cài đặt ứng dụng của bạn để thêm liên kết tượng trưng từ thư mục phương tiện của họ hoặc sao chép toàn bộ nội dung.

+0

Và làm cách nào để tránh các xung đột đặt tên/tham chiếu đến nó trong mã của tôi? Nếu tôi có ứng dụng "foo" với thư mục phương tiện và ứng dụng "thanh" có thư mục phương tiện, thì làm thế nào để tôi tham khảo thư mục bên trong mẫu ứng dụng mà không gây ra sự cố? –

+1

Nếu ứng dụng của bạn được gọi là 'foobar', hãy tham khảo phương tiện của bạn bằng cách sử dụng' {{MEDIA_URL}} foobar/myawesomejs.js'. Yêu cầu người dùng của bạn thiết lập liên kết tượng trưng tại 'foobar' trong thư mục phương tiện của họ. –

+0

Tôi nghĩ rằng câu trả lời của tôi dưới đây (sử dụng django-staticfiles) là một giải pháp toàn diện tốt hơn; đặc biệt là vì nó trông giống như một cái gì đó dựa trên staticfiles có thể được bao gồm trực tiếp trong Django 1.3. –

2

tôi thường đặt ứng dụng phương tiện vào./ Apps/appname/tĩnh (ứng dụng của tôi nằm trong một thư mục con ứng dụng)

sau đó tôi có một cái gì đó tương tự trong vhost trong apache:

AliasMatch ^/apps/([^/]+)/static/(.*) /home/django/projectname/apps/$1/static/$2 
<DirectoryMatch "^/home/django/projectname/apps/([^/]+)/static/*"> 
     Order deny,allow 
     Options -Indexes 
     deny from all 
     Options +FollowSymLinks 
     <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|txt|htm|html|json)$"> 
       allow from all 
     </FilesMatch> 
</DirectoryMatch> 

tôi cũng có điều này trong urls.py tôi cho máy chủ dev (chỉ sử dụng cho debug):

def statics_wrapper(request, **dict): 
    from django.views import static 
    return static.serve(request, dict['path'], document_root = os.path.join(settings.BASE_DIR, 'apps', dict['app'], 'static'), show_indexes=True) 
urlpatterns += patterns('', (r'^apps/(?P<app>[^/]+)/static/(?P<path>.+)$', statics_wrapper)) 

này là rất tiện dụng vì url tĩnh học chỉ đơn giản là ánh xạ tới hệ thống tập tin, ví dụ:

http://wwww.ecample.com/apps/calendar/static/js/calendar.js nằm trong [BASE_DIR]/apps/calend ar// tĩnh js/calendar.js

hy vọng điều này giúp

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