İçeriğe geç

Django Kullanıcı Modelini Genişletmek

Okuma süresi 4 dakika

Merhabalar. Django’nun yerleşik kullanıcı modeli gerçekten kuvvetli. Çoğu zaman direkt kullanım için uygun. Fakat gelen bazı istekler karşısında kullanıcı modelimizde değişiklikler yapmamız gerekebilir. Örneğin bir sosyal platform tasarlıyorsunuz ve kullanıcılarızın doğum tarihi, fotoğrafı gibi profilini oluşturacak bilgileri de saklamak istiyorsunuz. Veya yeni ORM sorguları ekleyerek yönetimi kolaylaştırmak isteyebilirsiniz. Bunun için modelinizi genişletmeniz ve yeni özellikler kazandırmanız gerekmekte.

Bunu yapmanın ise 4 farklı yolu var fakat 3 tanesini anlatacağım hazırsanız  başlayalım. Temiz bir proje oluşturarak devam edin.


1) Proxy Model Kullanmak.

Django’nun modelde halihazırda tuttuğu alanlar sizin icin yeterli fakat yeni metodlar eklemek veya model sıralamasını degiştirmek istiyorsanız kullanabilirsiniz.

Bir çok süper kullanıcıya sahip bir sisteminiz olduğunu varsayalım. Ve siz hepsine tek bir sorgu ile erişmek isteyebilirsiniz. (filter metodu’da iş görecektir) fakat bir çok yerde kullanmanız gereken spesifik sorgular var ve tekrar etmek istemiyorsunuz. Yerleşik kullanıcı sisteminde olmayan sorguları ek bir model manager tanımlayıp CustomUser’a atayıp User modelinizi genişleterek,yerleşik kullanıcı sistemine hiç dokunmadan işlerinizi yeni proxy modelinizden halledebilirsiniz veya anlamsız da olsa statik metotlar ekleyerek dünyayı selamlayabilirsiniz 🙂 CustomUser.objects.getSuperUsers() ve User.objects.filter(is_superuser=True) size aynı sonucu dönecektir. Tek dezavantajı bu metodlar chainable yani zincirlenerek kullanılamaz. Yani oluşturuduğunuz diğer sorguları kullanamazsınız. Yerleşik filtreler çalışır. (filter,exclude) Bunun önüne geçmek için Queryset sınıfı oluşturup metodlar tanımlamak daha avantajlı olabilir.


2) One To One Link ile Genişletme.

Açıkcası benim projelerimde en çok kullandığım yöntem bu. Yeni eklemek istediğiniz alanlar var ama yerleşik modelinizi terk etmek istemiyorsunuz. One to One ilişki kurarak yeni bir profil modeli tanımlıyor ve ek bilgileri orada barındırıyorsunuz. Örnekleyecek olursak şöyle bir model iş görecektir.

Bu haliyle devam ederseniz kullanıcı üzerinden profiline erişmeye çalıştığınız zaman işlem yaptığınız nesnenin öyle bir model ile bağlantılı olduğunu bilmediğinden dolayı profil bulunamadı hatası alırsınız.  Projeniz ilerledi ve fark etmeden böyle devam ettiniz diyelim. Her profile erişmeye çalıştığınız sayfada işleme giren kullanıcı nesnesinin attribute lerini kontrol etmeniz ve profil yok ise yönlendirme yaparak oluşturmaya zorlamanız gerekmekte. Ayrıyeten profil modelininde save metodunu her degisiklikte cağırmanız gerekmekte. O yüzden Django signals’i kullanmak daha akıllıca olabilir. Nedir diye konuşacak olursak? Django sinyalleri kısaca gerçekleşen işlemleri dinlemenizi ve bunlara göre aksiyon almanızı sağlar. Örneğin requestleri veya modellerin save metodlarının çalışmasını dinleyebilirsiniz.

receiver dekoratör ile sender olan User modelinin save metodunu dinliyoruz. Obje başarılı şekilde yaratılmış ise Profile modeline geçip user propu ile dönen user instance(nesne) ını eşitleyip ilişki kurup yeni bir profil nesnesi yaratıyoruz. Her nesne bir defa yaratılabileceğinden kontrolü sağladıktan sonra nesneyi yaratıyor. Eğer var ise de  var olan profil modelini yeni değerler ile kaydediyoruz. Aksi halde profil nesnesi üzerinde yapılabilecek olası değişiklikleri algılamayacaktır.

shell’e düstükten sonra birkaç örnek yapabilirsiniz.

Kullanıcıya kayıt olurken veya güncelleme yaparken profil bilgilerini doldurtmak isteyebilirsiniz bu gibi durumlarda tek sayfada 2 form ile mücadele etmeniz gerekbilir. Django Formset‘lere bakmanızı öneririm. Küçük bir not.

Bu konuyla ilgili bir yazı yazacağım. Devam edelim.


AbstractUser ve AbstractBaseUser kullanılırken dikkatli olunmalı. Halihazırda kullanılan user modelini projenin ortasında genişletmeye çalışmak akıllıca olmayabilir.  Veritabanı şeması fazlasıyla etkilenecektir. O yüzden bu yöntemlerden birini seçecekseniz projenizin başında konfigüre etmenizi öneririm. Sonuçta gereklilikleri belirlenmiş , ER diyagramları çizilmiş her şeyin nerede olduğunun belli olduğu projeyi kodlamaktan keyifli ne var ki 🙂

3) AbstractUser ile genişletme.

Django’nun hazır sisteminin sizin için iyi olduğunu düşünüyor ve ekstra model eklemek istemeden var olan kullanıcı modeli üzerine yeni özellikler eklemek istiyorsanız kullanabileceğiniz bir class AbstractUser.

Fakat diğer yollara göre biraz daha çetrefilli. Yapılması gereken daha fazla işlem var. Sırasıyla:

  1. settings.py ‘de User modeli degistirilmeli.
  2. User modelini baz alan formlar(UserCreationForm,UserChangeForm) kullanılacaksa güncellenmeli.
  3. Django admin panelinde yeni kazanılan özellikler için düzenleme yapılmalı.

Sırasıyla takip ediyorsanız yeni bir proje oluşturmakta istemiyorsanız migrations dosyalarınızı ve veritabanınızı silin.

Ben accounts adlı bir app oluşturmuştum o yüzden aşağıdaki değişikliği yapıyorum. Django’ya projeye başlamadan önce ben bu kullanıcı modelini kullanacağım. Kayıtları bunda tutar mısın diyorum.

Bu adımdan sonra migration komutlarınızı koşturabilirsiniz.

Formlara göz atalım.

Örnek verecek olursak UserCreationForm gayet kullanışlı ama default haliyle bizim yeni ekledigimiz alanları pas geçecek. Ve hata alacağız.

Gerekli alanları forma ekledik ve olusturulan kullanıcı nesnesine ekledik tamam görünüyor.

Admin kısmında ise Django User modeli icin diger model adminlerden farklı bir sınıf barındırıyor. UserAdmin.

Form alanlarına ekstra alanlarımızı ekledik. Ve şehir üstünden sorgulama için de basit bir filter ekledik.

Küçük bir not daha.

Kullanıcılarınızın giriş çıkış işlemleri yaparken örneğin email kullanmasını istiyorsunuz. Şöyle bir tanım ile üstesinden gelebilirsiniz.

Username için email kullanacağımızı belirttik. Ardından command prompttan verilen createsuperuser gibi komutlarda mutlak sorulması gereken alana username ekledik. Yanlış anlaşılmasın username alanının üstüne email yazmıyoruz. Herkes yine kendi yerinde sadece authentication işlemlerinde ’email’ propu kullanılsın diyoruz. Devam edebiliriz.

4) AbstractBaseUser ile genişletme.

Bu kullanım ile Django’nun hali hazırdaki kullanıcı modelinden hiç bir şey istemediğinizi belirtiyorsunuz. Birkaç istisna tabi ki var is_superuser date_joined gibi propları ve tabiki parolaları barındırmak zorunda. Ama bu işlemleri yapmak zaman açısından çok maliyetli olabilir. Açıkcası çok da tercih edilen bir yöntem olduğunu düşünmüyorum. Genel olarak 2. ve 3. yöntem her zaman iş görecek şekilde dizayn edilmiş. Tabii ki seçim sizin. Linki buraya bırakıyorum.


Özetleyecek olursam:

  • Her şeyden memnunum ama biraz da ben metod ekleyeyim derseniz Proxy modeller.
  • Her şeyden memnunum fakat daha fazla bilgi tutmak istiyorum ama modelimin doğrudan genişlemesini istemiyorum diyorsanız One to One modeller.
  • Genel olarak memnunum ama ekstra özellikler kazandırdığım modelimin authentication işlemlerinde de değişiklik yapmak istiyorum diyorsanız AbstractUser kullanabilirsiniz.
Tarih:Django DersleriPython

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Göster
Gizle