Flask Tutorial Entity Relationship

8-FlaskFollowers

Followers

  • Bu bölümde projemizde kullanıcıların birbirlerini takip etmesi için models.py'da düzenlemeler yapacağız.
  • Başlamadan önce kısa bir database relationship (veritabanı ilişki) tiplerine göz atalım.
One-To-Many

User-Post

  • User ve Post olarak belirttiğimiz iki adet varlık ile kullanıcı ve kullanıcı yayınları(gönderileri) ilişkisini tabloda gösteriyoruz.
  • Tabloda görüleceği üzere user_id posts tablosuna foreign key olarak verildi. Burada 1 adet User, 1'den fazla Post yayınlayabileceği için many tarafı posts tablosu, one tarafı users tablosudur.
  • Many tarafındaki tablo One tarafına bağlanabilmesi için üzerinde bir bağlantı taşıması gerekiyor. İşte bu bağlantı user_id olacak.
  • Ayrıca user_id üzerinden bir kullanıcıya ait yayınların(gönderilerin) listesine de erişebiliyoruz.
Many-To-Many

May-Many

  • Örnek tablodaki gibi 1 Öğrencinin, 1'den fazla Öğretmeni olabileceği gibi; 1 Öğretmenin de 1'den fazla Öğrencisi olabilir.
  • Many-To-Many ilişkisinde taraflara foreign key eklenemiyor.
  • Many-To-Many karmaşıklığını yardımcı tablolar vasıtası ile çözüyoruz.
  • Böylece 2 adet One-To-Many ilişkisi elde etmiş olduk.

Representing Followers (Takipçilerin Gösterimi)

Followers

  • Öğrenci & Öğretmen (Student & Teacher) ilişkisine benzer bir many-to-many ilişki de takip edilen & takipçi (followed & follower) arasındaki ilişkidir.
  • Student & Teacher varlıkları 2 adet tabloda temsil ediliyordu. Ancak bizim sadece User varlığımız ve bunun users tablosu elimizde mevcut.
  • Many-To-Many Relationship gerçekleşmesi için 2. varlık nedir? Bu da User varlığıdır.
  • Bu şekildeki gibi kendisini referans alan varlık yapılarına self-referential relationship ilişkisi deniliyor.
  • foreign key'ler followers tablosunda bulunuyor.
  • Şimdi followers tablosunu myapp/models.py modülüne ekleyelim
 
  • Tanımladığımız followers tablosu bir model sınıfı değildir. Yardımcı bir tablo olarak tanımladık.
  • Şimdi many-to-many ilişkisini User modeline uygulayalım. myapp/models.py
 
  • Yeniden db.relationship() methodu ile model sınıfları arası ilişki tanımlıyoruz. Burada User yukarıda tabloda gösterdiğimiz gibi kendisi ile ilişkisel bağlantı oluşturacak.

  • Burada followed referansı ile takip edilen kulanıcıların listesini alabileceğiz.

  • db.relationship() methodu parametrelerine bakarsak;

    • User ; ilişki kurulacak model adı. Burada aynı modeli kullandığımız için yine User model sınıfını verdik.
    • secondary; ilişki kurulacak yardımcı tablo ile konfigurasyon sağlar. Yardımcı tablomuz followers dır.
    • primaryjoin; follower user ile yardımcı tabloyu birbirine bağlayan şartı belirtir.
    • secondaryjoin; followed user ile yardımcı tabloyu birbirine bağlayan şartı belirtir.
    • backref; tablolar arası ilişkiye nasıl erişileceğini tanımlar. followed üzerinden followers'a erişmek diyebiliriz.
  • Şimdi terminalden migration yapalım:

 

Takip Ekleme/Silme (Adding/Removing Follows)

  • Örneğin user1 ve user2 adında iki kullanıcımızın olduğunu varsayalım.
  • user1 , user2'yi takip etmesi için; user1.followed.append(user2) yazabiliriz.
  • Takip'ten çıkması için de user1.followed.remove(user2) yazabiliriz.
  • Listelerdeki append ve remove methodları ile çok basit şekilde yapabiliyoruz.
  • Ancak kodlarımızın daha efektif ve yeniden kullanılabilir olması için ekleme, silme işlemlerini kendi methodlarımız üzerinden yapacağız.
  • myapp/models.py
 
  • is_following() methodu yardımı ile takip edip etmediği kontrolü yapıyoruz.

Takip edilenlerin gönderilerini listelemek (Obtaining the Posts from Followed Users)

  • myapp/models.py
 
  • Post.query.join(...).filter(...).order_by(...) açıklayalım.
JOIN
  • User tablosu aşağıdaki gibi olsun.
idusername
1Adnan
2Abdullah
3Murat
4Mehmet
  • followers yardımcı tablomuz da aşağıdaki gibi olsun.
follower_idfollowed_id
12
14
23
34
  • Adnan Abdullah'ı ve Mehmet'i;
  • Abdullah Murat'ı;
  • Murat da Mehmet'i takip ediyor.
  • posts tablosu
idtextuser_id
1post from Abdullah2
2post from Murat3
3post from Mehmet4
4post from Adnan1
  • Post.query.join(followers, (followers.c.followed_id == Post.user_id))

    • ilk argüman followers; yardımcı tablo
    • ikinci argüman join şartı.
    • Burada diyoruz ki database'e; bizim için geçici bir tablo oluştur ve posts tablosu ile followers tablosunu birleştir ancak bizim belirttiğimiz şarta göre!
    • Şart: takip edilen kullanıcı ID'si , Post tablosundaki kullanıcı ID'si ile eşleşmelidir.
idtextuser_idfollower_idfollowed_id
1post from Abdullah212
2post from Murat323
3post from Mehmet414
3post from Mehmet434
  • user_id ile followed_id birbirine eşit durumda! (join şartımız.)
  • Adnan kullanıcısını kimse takip etmediği için tabloda yok.
  • Mehmet'i 2 kişi takip ettiği için 2 adet post kaydı var tablomuzda.
Filters
  • Şimdi sadece 1 kullanıcının takip ettiği kişilerin gönderilerini almak için filtreleme yapalım.

  • filter(followers.c.follower_id == self.id)

    • self.id; user ID'dir.
  • Örneğin Adnan kullanıcısının takip ettiği kullanıcıların listesi:

idtextuser_idfollower_idfollowed_id
1post from Abdullah212
3post from Mehmet414
Sorting
  • Sıralama için : order_by(Post.timestamp.desc())

    • Son yayınlanan post'ları almak için sıralama yapıldı.
Mevcut kullanıcı ve takipçilerin gönderilerinin birleştirilmesi (Combining own user and followed posts)
  • myapp/models.py
 
  • followed; ile takip edilenlerin gönderilerini,
  • own; ile mevcut kullanıcının gönderilerini alıyoruz.
  • followed.union(own) diyerek bu iki listeyi birleştiriyoruz.
  • son olarak order_by ile sıralıyoruz.

Takipçileri Projeye Entegre Etmek (Integrating Followers)

  • myapp/routes.py
 
  • myapp/templates/user.html
 
  • {% if user==current_user %}; mevcut kullanıcı Edit Profile linki görülür.
  • {% elif not current_user.is_following(user)%}; mevcut kullanıcı değilse ve profilini ziyaret ettiğimiz kullanıcı takip edilmiyorsa, Follow linki görülür.
  • {% else %}; mevcut kullanıcı değil ve profili ziyaret edilen kullanıcı takip ediliyorsa, Unfollow linki görülür.
  • Ekran Görüntüleri ssp1

ssp2

 

Yorumlar