Farklı projeler/veritabanları için aynı uygulamayı kullanmak için this yanıtından esinlenen URL tabanlı veritabanı yönlendirmesini ayarlıyorum. Projelerin herhangi bir veriyi paylaşması gerekmiyor, erişim kontrolü kendi başına her proje tarafından yönetiliyor ve her proje için bir yönetici sitesine ihtiyacım var. Orijinal yazıda olduğu gibi, bir veritabanı yönlendiricisi ve istek yolundan hangi veritabanının kullanılacağını belirleyen bir ara katman kullanıyorum. /test/process/1
, test
ve /default/process/2
numaralı veritabanına default
numaralı veritabanına yönlendirilecektir.URL tabanlı veritabanı yönlendirme
import threading
from django.conf import settings
request_cfg = threading.local()
class RouterMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
path = request.path.lstrip('/').split('/')
if path[0] in settings.DATABASES:
request_cfg.db = path[0]
def process_response(self, request, response):
if hasattr(request_cfg, 'db'):
del request_cfg.db
return response
class DatabaseRouter(object):
def _default_db(self):
if hasattr(request_cfg, 'db') and request_cfg.db in settings.DATABASES:
return request_cfg.db
else:
return 'default'
def db_for_read(self, model, **hints):
return self._default_db()
def db_for_write(self, model, **hints):
return self._default_db()
URL kalıpları daha sonra belirli bir veritabanı belirtmektedir alt yolunu kapsayacak şekilde genişletilebilir gerekir. Böyle bir proje düzeyi urls.py içinde URL'ler hardcoding bunu yapıp yapmadığını:
urlpatterns = [
url(r'^default/admin/', include(admin.site.urls)), # does not work
url(r'^test/admin/', include(admin.site.urls)), # does not work
url(r'^default/', include('logbook.urls', namespace='anything')),
url(r'^test/', include('logbook.urls', namespace='anything else'))]
Bu çok güzel olmadığını itiraf ama birkaç veritabanları daha yönetmek zorunda beklemeyin. İlginçtir ki, ad alanı argümanının ne olduğu önemli değil, ama verilmesi gerekiyor. Uygulamanın orijinal ad alanı, logbook
idi ve uygulamanın tüm görünümleri ve şablonlarının tersine URL'yi geri almak için kullanılır.
Daha sonra, uygulama düzeyinde app_name tanımlanan (ve orijinal ad eşit) olmak zorundadır urls.py: görünümlerinde
app_name = 'logbook'
urlpatterns = [
url(r'^$', views.redirect_index, name='index'),
url(r'^(?P<date>[0-9]{4}[0-9]{2})/$', views.Index.as_view(), name='index'),
.....
I reverse()
her çağrı olarak bir current_app=request.resolver_match.namespace
kwarg eklendi django dokümanlarında açıkladı. Şablonların içinde yer alan URL'lerin çözümünde herhangi bir değişiklik yapılması gerekmedi.
Genel olarak bu iki istisna dışında çok iyi çalışıyor: Her zaman urls.py ilk girdiye çözecektir yönetici görünümleri herhangi biri için ters
- url
- Ben çoğunlukla
django.contrib.auth.middleware.AuthenticationMiddleware
ile çalışmak yapamaz Bence,LOGIN
veLOGIN_REDIRECT
sabitleridir.
Bu temiz bir yaklaşım olup olmadığını merak ve ediyorum yukarıda bahsedilen iki istisna dışında çözüm varsa. Değilse, daha iyi bir çözüm ne olurdu?
Nasıl konuşlanıyorsunuz? Bana göre yapılacak en iyi şey, sunucunuzun yapılandırmasındaki URL'leri, ör. apache, ve sonra sadece iki tamamen ayrı django wsgi uygulamaları kullanın, bu yüzden bunlardan endişelenmenize gerek yok. Ben django yönetici uygulaması birden fazla veritabanı ile güzel oynayacağını sanmıyorum. Birden fazla kullanıcı veritabanına ihtiyacınız olmasa da, yönetici ve auth vb. Veritabanlarını tek bir veritabanında merkezileştirerek biraz yol alabilirsiniz. – daphtdazz
Henüz konuşmayı düşünmedim, python web sunucusu ile çalışıyorum. Her neyse, daha fazla sorun olacağını umuyorum. Medya dosyaları ile ve dediğiniz gibi, yönetici uygulamasının birden çok veritabanında çalışacağı görünmüyor. Muhtemelen hepsini tek bir veritabanında bırakacağım. Düşüncelerin için teşekkürler. –