Ví dụ liên kết trong python

Tôi đã thấy rất nhiều bài đăng trên Stackoverflow giải thích sự khác biệt giữa các mối quan hệ. các hiệp hội, tập hợp, thành phần và kế thừa, với các ví dụ. Tuy nhiên, tôi đặc biệt bối rối hơn về những ưu và nhược điểm của từng cách tiếp cận này và khi nào một cách tiếp cận hiệu quả nhất cho nhiệm vụ trong tay. Đây là điều mà tôi đã không thể thực sự tìm thấy một câu trả lời hay trên

Theo đúng hướng dẫn của diễn đàn, tôi không hỏi tại sao cá nhân mọi người có thể thích sử dụng tính kế thừa hơn thành phần, chẳng hạn. Tôi đặc biệt quan tâm đến bất kỳ lợi ích/điểm yếu khách quan nào trong mỗi cách tiếp cận, dù điều đó nghe có vẻ mạnh mẽ đến mức nào. Tôi. e. một cách tiếp cận có tạo ra nhiều mã dễ đọc hơn cách tiếp cận khác hay nó có hiệu quả thời gian chạy tốt hơn, v.v.

Lý tưởng nhất là nếu ai đó có thể cho tôi một số ví dụ thực tế về những cách tiếp cận này có thể thành công hay thất bại và tại sao, điều đó sẽ cực kỳ hữu ích cho việc phát triển kiến ​​thức của tôi và, tôi hy vọng, của những người khác.

Để đảm bảo cơ sở vững chắc hoạt động, tôi đã đưa vào các ví dụ về từng mối quan hệ trong Python 2. Hy vọng rằng điều này sẽ cho phép tránh nhầm lẫn, nếu sự hiểu biết của tôi về những mối quan hệ này không thực sự chính xác

Sự kết hợp

Lớp B có mối quan hệ liên kết theo tuần với Lớp A, vì nó sử dụng các thuộc tính cụ thể từ A trong phương thức addAllNums. Tuy nhiên, đó là mức độ của mối quan hệ

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e

    def addAllNums(self, Ab, Ac):
        x = self.d + self.e + Ab + Ac
        return x

ting = A("yo", 2, 6)
ling = B(5, 9)

print ling.addAllNums(ting.b, ting.c)

tổng hợp

Lớp B hình thành mối quan hệ tổng hợp với Lớp A, vì nó tham chiếu đến một đối tượng A độc lập khi được khởi tạo, như một trong các thuộc tính của nó. Trong khi một đối tượng B phụ thuộc vào A, trong trường hợp B bị phá hủy, A sẽ tiếp tục tồn tại vì nó độc lập với B

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()

Thành phần

Giống như tập hợp, tuy nhiên, thay vì tham chiếu đến một đối tượng độc lập, B thực sự khởi tạo một thể hiện của A trong hàm tạo của chính nó như một thuộc tính. Nếu đối tượng B bị hủy thì đối tượng A cũng vậy. Đây là lý do tại sao thành phần là một mối quan hệ mạnh mẽ như vậy

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e
        self.A = A("yo", 2, 6)

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ling = B(5, 9)

print ling.addAllNums() 

Tôi đã quyết định không đưa vào một ví dụ về thừa kế vì tôi hoàn toàn hài lòng với nó và tôi cảm thấy rằng việc đưa vào đó có thể khiến vấn đề trở nên lạc đề một chút.

Bất kể, một lần nữa, những ưu và nhược điểm của các ví dụ trên và kế thừa (so với nhau) là gì

Đây là phần thứ tám của sê-ri Flask Mega-Tutorial, trong đó tôi sẽ cho bạn biết cách triển khai tính năng "người theo dõi" tương tự như tính năng của Twitter và các mạng xã hội khác

Để bạn tham khảo, dưới đây là danh sách các bài viết trong loạt bài này

  • Chương 1. Chào thế giới
  • chương 2. mẫu
  • Chương 3. biểu mẫu web
  • Chương 4. cơ sở dữ liệu
  • Chương 5. Đăng nhập người dùng
  • Chương 6. Trang hồ sơ và hình đại diện
  • Chương 7. Xử lý lỗi
  • Chương 8. Người theo dõi (bài viết này)
  • Chương 9. phân trang
  • Chương 10. Hỗ trợ email
  • chương 11. căng da mặt
  • Chương 12. Ngày và Giờ
  • Chương 13. I18n và L10n
  • Chương 14. Ajax
  • Chương 15. Cấu trúc ứng dụng tốt hơn
  • Chương 16. Tìm kiếm toàn văn
  • Chương 17. Triển khai trên Linux
  • Chương 18. Triển khai trên Heroku
  • Chương 19. Triển khai trên Docker Container
  • Chương 20. Một số ma thuật JavaScript
  • Chương 21. Thông báo người dùng
  • Chương 22. công việc nền
  • Chương 23. Giao diện lập trình ứng dụng (API)

Trong chương này tôi sẽ làm việc trên cơ sở dữ liệu của ứng dụng một số chi tiết. Tôi muốn người dùng của ứng dụng có thể dễ dàng chọn những người dùng khác mà họ muốn theo dõi. Vì vậy, tôi sẽ mở rộng cơ sở dữ liệu để nó có thể theo dõi xem ai đang theo dõi ai, điều này phức tạp hơn bạn nghĩ

Các liên kết GitHub cho chương này là. Duyệt, Zip, Khác biệt

Mối quan hệ cơ sở dữ liệu được xem lại

Tôi đã nói ở trên rằng tôi muốn duy trì danh sách người dùng "được theo dõi" và "người theo dõi" cho mỗi người dùng. Thật không may, cơ sở dữ liệu quan hệ không có loại danh sách mà tôi có thể sử dụng cho các danh sách này, tất cả chỉ có các bảng có bản ghi và mối quan hệ giữa các bản ghi này

Cơ sở dữ liệu có một bảng đại diện cho người dùng, vì vậy điều còn lại là tìm ra loại mối quan hệ phù hợp có thể mô hình hóa liên kết theo dõi/được theo dõi. Đây là thời điểm tốt để xem lại các kiểu quan hệ cơ sở dữ liệu cơ bản

Một-nhiều

Tôi đã sử dụng mối quan hệ một-nhiều trong Chương 4. Đây là sơ đồ cho mối quan hệ này

Ví dụ liên kết trong python

Hai thực thể được liên kết bởi mối quan hệ này là người dùng và bài đăng. Tôi nói rằng một người dùng có nhiều bài đăng và một bài đăng có một người dùng (hoặc tác giả). Mối quan hệ được thể hiện trong cơ sở dữ liệu với việc sử dụng khóa ngoại ở phía "nhiều". Trong mối quan hệ trên, khóa ngoại là trường

user1.followed.remove(user2)
3 được thêm vào bảng
user1.followed.remove(user2)
4. Trường này liên kết từng bài đăng với bản ghi của tác giả trong bảng người dùng

Rõ ràng là trường

user1.followed.remove(user2)
3 cung cấp quyền truy cập trực tiếp đến tác giả của một bài đăng nhất định, nhưng còn hướng ngược lại thì sao? . Trường
user1.followed.remove(user2)
3 trong bảng
user1.followed.remove(user2)
4 cũng đủ để trả lời câu hỏi này, vì cơ sở dữ liệu có các chỉ mục cho phép thực hiện các truy vấn hiệu quả, chẳng hạn như chúng tôi "truy xuất tất cả các bài đăng có user_id của X"

Nhiều nhiều

Mối quan hệ nhiều-nhiều phức tạp hơn một chút. Ví dụ, hãy xem xét một cơ sở dữ liệu có

user1.followed.remove(user2)
8 và
user1.followed.remove(user2)
9. Tôi có thể nói rằng một học sinh có nhiều giáo viên và một giáo viên có nhiều học sinh. Nó giống như hai mối quan hệ một-nhiều chồng lên nhau từ cả hai đầu

Đối với mối quan hệ kiểu này, tôi có thể truy vấn cơ sở dữ liệu và lấy danh sách giáo viên dạy một học sinh nhất định và danh sách học sinh trong lớp của giáo viên. Điều này thực sự không tầm thường để biểu diễn trong cơ sở dữ liệu quan hệ, vì nó không thể được thực hiện bằng cách thêm các khóa ngoại vào các bảng hiện có

Biểu diễn mối quan hệ nhiều-nhiều yêu cầu sử dụng một bảng phụ gọi là bảng liên kết. Đây là cách cơ sở dữ liệu sẽ tìm kiếm ví dụ về học sinh và giáo viên

Ví dụ liên kết trong python

Mặc dù ban đầu có vẻ không rõ ràng, nhưng bảng kết hợp với hai khóa ngoại của nó có thể trả lời hiệu quả tất cả các truy vấn về mối quan hệ

Nhiều-một và Một-một

Mối quan hệ nhiều-một tương tự như mối quan hệ một-nhiều. Điểm khác biệt là mối quan hệ này được nhìn từ phía "nhiều"

Mối quan hệ một đối một là trường hợp đặc biệt của mối quan hệ một đối nhiều. Biểu diễn tương tự, nhưng một ràng buộc được thêm vào cơ sở dữ liệu để ngăn phía "nhiều" có nhiều liên kết. Mặc dù có những trường hợp loại mối quan hệ này hữu ích, nhưng nó không phổ biến như các loại khác

Đại diện cho những người theo dõi

Nhìn vào bản tóm tắt của tất cả các loại mối quan hệ, có thể dễ dàng xác định rằng mô hình dữ liệu phù hợp để theo dõi người theo dõi là mối quan hệ nhiều-nhiều, bởi vì một người dùng theo dõi nhiều người dùng và một người dùng có nhiều người theo dõi. Nhưng có một sự thay đổi. Trong ví dụ về sinh viên và giáo viên, tôi có hai thực thể có liên quan thông qua mối quan hệ nhiều-nhiều. Nhưng trong trường hợp người theo dõi, tôi có người dùng theo dõi người dùng khác, vì vậy chỉ có người dùng. Vậy thực thể thứ hai của mối quan hệ nhiều-nhiều là gì?

Thực thể thứ hai của mối quan hệ cũng là người dùng. Mối quan hệ trong đó các thể hiện của một lớp được liên kết với các thể hiện khác của cùng một lớp được gọi là mối quan hệ tự tham chiếu và đó chính xác là những gì tôi có ở đây

Đây là sơ đồ về mối quan hệ nhiều-nhiều tự tham chiếu để theo dõi những người theo dõi

Ví dụ liên kết trong python

Bảng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
00 là bảng liên kết của mối quan hệ. Các khóa ngoại trong bảng này đều trỏ vào các mục trong bảng người dùng, vì nó đang liên kết người dùng với người dùng. Mỗi bản ghi trong bảng này đại diện cho một liên kết giữa người dùng theo dõi và người dùng được theo dõi. Giống như ví dụ về học sinh và giáo viên, một thiết lập như thế này cho phép cơ sở dữ liệu trả lời tất cả các câu hỏi về người dùng được theo dõi và người theo dõi mà tôi sẽ cần. khá gọn gàng

Biểu diễn mô hình cơ sở dữ liệu

Trước tiên hãy thêm người theo dõi vào cơ sở dữ liệu. Đây là bảng liên kết

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
00

ứng dụng/mô hình. py. Bảng hiệp hội người theo dõi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
2

Đây là bản dịch trực tiếp của bảng liên kết từ sơ đồ của tôi ở trên. Lưu ý rằng tôi không khai báo bảng này dưới dạng một mô hình, giống như tôi đã làm với bảng người dùng và bài đăng. Vì đây là một bảng phụ không có dữ liệu nào khác ngoài các khóa ngoại nên tôi đã tạo nó mà không có lớp mô hình liên quan

Bây giờ tôi có thể khai báo mối quan hệ nhiều-nhiều trong bảng người dùng

ứng dụng/mô hình. py. Mối quan hệ nhiều người theo dõi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
3

Việc thiết lập mối quan hệ là không tầm thường. Giống như tôi đã làm với mối quan hệ một-nhiều của

user1.followed.remove(user2)
4, tôi đang sử dụng hàm
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
03 để xác định mối quan hệ trong lớp mô hình. Mối quan hệ này liên kết các phiên bản
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04 với các phiên bản
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04 khác, do đó, theo quy ước, giả sử rằng đối với một cặp người dùng được liên kết bởi mối quan hệ này, người dùng bên trái sẽ theo dõi người dùng bên phải. Tôi đang xác định mối quan hệ được nhìn thấy từ người dùng bên trái có tên
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
06, bởi vì khi tôi truy vấn mối quan hệ này từ phía bên trái, tôi sẽ nhận được danh sách những người dùng được theo dõi (tôi. e những người ở phía bên phải). Hãy xem xét tất cả các đối số cho lệnh gọi
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
07 từng cái một

  • class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e, A):
            self.d = d
            self.e = e
            self.A = A
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ting = A("yo", 2, 6)
    ling = B(5, 9, ting)
    
    print ling.addAllNums()
    
    08 là thực thể bên phải của mối quan hệ (thực thể bên trái là lớp cha). Vì đây là mối quan hệ tự tham chiếu, tôi phải sử dụng cùng một lớp cho cả hai bên
  • class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e, A):
            self.d = d
            self.e = e
            self.A = A
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ting = A("yo", 2, 6)
    ling = B(5, 9, ting)
    
    print ling.addAllNums()
    
    09 định cấu hình bảng liên kết được sử dụng cho mối quan hệ này mà tôi đã xác định ngay phía trên lớp này
  • class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    20 cho biết điều kiện liên kết thực thể bên trái (người dùng theo dõi) với bảng liên kết. Điều kiện nối cho phía bên trái của mối quan hệ là ID người dùng khớp với trường
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    21 của bảng liên kết. Giá trị của đối số này là
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    22, tham chiếu đến cột
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    21 của bảng liên kết
  • class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    24 cho biết điều kiện liên kết thực thể bên phải (người dùng được theo dõi) với bảng liên kết. Điều kiện này tương tự như điều kiện cho
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    20, với điểm khác biệt duy nhất là hiện tôi đang sử dụng
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    26, đây là khóa ngoại khác trong bảng kết hợp
  • class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    27 xác định cách truy cập mối quan hệ này từ thực thể bên phải. Từ phía bên trái, mối quan hệ được đặt tên là
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e, A):
            self.d = d
            self.e = e
            self.A = A
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ting = A("yo", 2, 6)
    ling = B(5, 9, ting)
    
    print ling.addAllNums()
    
    06, vì vậy, từ phía bên phải, tôi sẽ sử dụng tên
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e, A):
            self.d = d
            self.e = e
            self.A = A
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ting = A("yo", 2, 6)
    ling = B(5, 9, ting)
    
    print ling.addAllNums()
    
    00 để đại diện cho tất cả những người dùng bên trái được liên kết với người dùng mục tiêu ở phía bên phải. Đối số bổ sung
    user1.followed.remove(user2)
    
    20 cho biết chế độ thực thi cho truy vấn này. Chế độ
    user1.followed.remove(user2)
    
    21 thiết lập truy vấn không chạy cho đến khi được yêu cầu cụ thể, đây cũng là cách tôi thiết lập mối quan hệ một-nhiều của bài đăng
  • user1.followed.remove(user2)
    
    20 tương tự như tham số cùng tên trong
    class A(object):
        def __init__(self, a, b, c):
            self.a = a
            self.b = b
            self.c = c
    
        def addNums():
            self.b + self.c
    
    class B(object):
        def __init__(self, d, e):
            self.d = d
            self.e = e
            self.A = A("yo", 2, 6)
    
        def addAllNums(self):
            x = self.d + self.e + self.A.b + self.A.c
            return x
    
    ling = B(5, 9)
    
    print ling.addAllNums() 
    
    27, nhưng tham số này áp dụng cho truy vấn bên trái thay vì bên phải

Đừng lo lắng nếu điều này khó hiểu. Tôi sẽ chỉ cho bạn cách làm việc với các truy vấn này trong giây lát và sau đó mọi thứ sẽ trở nên rõ ràng hơn

Những thay đổi đối với cơ sở dữ liệu cần được ghi lại trong quá trình di chuyển cơ sở dữ liệu mới

user1.followed.remove(user2)
6

Thêm và xóa "theo dõi"

Nhờ SQLAlchemy ORM, một người dùng theo dõi một người dùng khác có thể được ghi lại trong cơ sở dữ liệu làm việc với mối quan hệ

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
06 như thể đó là một danh sách. Ví dụ: nếu tôi có hai người dùng được lưu trữ trong các biến
user1.followed.remove(user2)
25 và
user1.followed.remove(user2)
26, tôi có thể tạo người đầu tiên theo sau người thứ hai bằng câu lệnh đơn giản này

user1.followed.remove(user2)
0

Để ngừng theo dõi người dùng, sau đó tôi có thể làm

user1.followed.remove(user2)

Mặc dù việc thêm và xóa người theo dõi khá dễ dàng, nhưng tôi muốn thúc đẩy khả năng sử dụng lại trong mã của mình, vì vậy tôi sẽ không thêm "thêm vào" và "xóa" thông qua mã. Thay vào đó, tôi sẽ triển khai chức năng "theo dõi" và "bỏ theo dõi" như các phương thức trong mô hình

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04. Tốt nhất là luôn chuyển logic ứng dụng ra khỏi các chức năng xem và chuyển sang các mô hình hoặc các lớp hoặc mô-đun phụ trợ khác, bởi vì như bạn sẽ thấy ở phần sau của chương này, điều đó làm cho việc kiểm thử đơn vị dễ dàng hơn nhiều

Dưới đây là những thay đổi trong mô hình người dùng để thêm và xóa các mối quan hệ

ứng dụng/mô hình. py. Thêm và xóa người theo dõi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
0

Các phương thức

user1.followed.remove(user2)
28 và
user1.followed.remove(user2)
29 sử dụng các phương thức
user1.followed.remove(user2)
60 và
user1.followed.remove(user2)
61 của đối tượng mối quan hệ như tôi đã trình bày ở trên, nhưng trước khi chạm vào mối quan hệ, chúng sử dụng phương thức hỗ trợ
user1.followed.remove(user2)
62 để đảm bảo hành động được yêu cầu có ý nghĩa. Ví dụ: nếu tôi yêu cầu
user1.followed.remove(user2)
25 theo dõi
user1.followed.remove(user2)
26, nhưng hóa ra mối quan hệ sau này đã tồn tại trong cơ sở dữ liệu, tôi không muốn thêm trùng lặp. Logic tương tự có thể được áp dụng để bỏ theo dõi

Phương thức

user1.followed.remove(user2)
62 đưa ra một truy vấn về mối quan hệ
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
06 để kiểm tra xem đã tồn tại liên kết giữa hai người dùng chưa. Bạn đã thấy tôi sử dụng phương pháp
user1.followed.remove(user2)
67 của đối tượng truy vấn SQLAlchemy trước đây, chẳng hạn để tìm một người dùng được cung cấp tên người dùng của họ. Phương pháp
user1.followed.remove(user2)
68 mà tôi đang sử dụng ở đây cũng tương tự, nhưng ở cấp độ thấp hơn, vì nó có thể bao gồm các điều kiện lọc tùy ý, không giống như
user1.followed.remove(user2)
67 chỉ có thể kiểm tra sự bằng nhau với một giá trị không đổi. Điều kiện mà tôi đang sử dụng trong
user1.followed.remove(user2)
62 tìm kiếm các mục trong bảng liên kết có khóa ngoại bên trái được đặt thành người dùng
user1.followed.remove(user2)
71 và bên phải được đặt thành đối số
user1.followed.remove(user2)
72. Truy vấn được kết thúc bằng phương thức
user1.followed.remove(user2)
73, phương thức này trả về số lượng kết quả. Kết quả của truy vấn này sẽ là
user1.followed.remove(user2)
74 hoặc
user1.followed.remove(user2)
75, vì vậy việc kiểm tra số đếm bằng 1 hoặc lớn hơn 0 thực sự là tương đương. Các dấu kết thúc truy vấn khác mà bạn đã thấy tôi sử dụng trước đây là ________ 576 và ________ 577

Lấy bài viết từ người dùng được theo dõi

Hỗ trợ cho những người theo dõi trong cơ sở dữ liệu gần như đã hoàn tất, nhưng tôi thực sự đang thiếu một tính năng quan trọng. Trong trang chỉ mục của ứng dụng, tôi sẽ hiển thị các bài đăng trên blog được viết bởi tất cả những người được theo dõi bởi người dùng đã đăng nhập, vì vậy tôi cần đưa ra một truy vấn cơ sở dữ liệu trả về các bài đăng này

Giải pháp rõ ràng nhất là chạy một truy vấn trả về danh sách những người dùng được theo dõi, như bạn đã biết, nó sẽ là

user1.followed.remove(user2)
78. Sau đó, đối với mỗi người dùng đã quay lại này, tôi có thể chạy truy vấn để nhận các bài đăng. Khi tôi có tất cả các bài đăng, tôi có thể hợp nhất chúng thành một danh sách và sắp xếp chúng theo ngày. Âm thanh tốt?

Cách tiếp cận này có một vài vấn đề. Điều gì xảy ra nếu người dùng đang theo dõi một nghìn người? . Và sau đó tôi sẽ cần hợp nhất và sắp xếp hàng nghìn danh sách trong bộ nhớ. Là một vấn đề phụ, hãy xem xét rằng trang chủ của ứng dụng cuối cùng sẽ được triển khai phân trang, vì vậy nó sẽ không hiển thị tất cả các bài đăng có sẵn mà chỉ hiển thị một số bài đăng đầu tiên, với liên kết để tải thêm nếu muốn. Nếu tôi định hiển thị các bài đăng được sắp xếp theo ngày của chúng, làm cách nào để biết bài đăng nào là gần đây nhất trong số tất cả những người dùng được theo dõi cộng lại, trừ khi tôi lấy tất cả các bài đăng và sắp xếp chúng trước?

Thực sự không có cách nào để tránh việc hợp nhất và sắp xếp các bài đăng trên blog này, nhưng thực hiện nó trong ứng dụng dẫn đến một quy trình rất kém hiệu quả. Loại công việc này là những gì cơ sở dữ liệu quan hệ vượt trội. Cơ sở dữ liệu có các chỉ mục cho phép nó thực hiện các truy vấn và sắp xếp theo cách hiệu quả hơn nhiều mà tôi có thể làm từ phía mình. Vì vậy, điều tôi thực sự muốn là đưa ra một truy vấn cơ sở dữ liệu duy nhất xác định thông tin mà tôi muốn lấy, sau đó để cơ sở dữ liệu tìm ra cách trích xuất thông tin đó theo cách hiệu quả nhất

Dưới đây bạn có thể thấy truy vấn này

ứng dụng/mô hình. py. Truy vấn bài đăng đã theo dõi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e
        self.A = A("yo", 2, 6)

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ling = B(5, 9)

print ling.addAllNums() 
2

Đây là truy vấn phức tạp nhất mà tôi đã sử dụng trên ứng dụng này. Tôi sẽ cố gắng giải mã truy vấn này từng mảnh một. Nếu bạn nhìn vào cấu trúc của truy vấn này, bạn sẽ nhận thấy rằng có ba phần chính được thiết kế bởi các phương thức

user1.followed.remove(user2)
79,
user1.followed.remove(user2)
68 và
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
301 của đối tượng truy vấn SQLAlchemy

user1.followed.remove(user2)
2

tham gia

Để hiểu thao tác nối làm gì, hãy xem một ví dụ. Giả sử rằng tôi có một bảng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04 với các nội dung sau

idusername1john2susan3mary4david

Để đơn giản, tôi không hiển thị tất cả các trường trong mô hình người dùng, chỉ hiển thị những trường quan trọng đối với truy vấn này

Giả sử bảng liên kết

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
00 nói rằng người dùng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
304 đang theo dõi người dùng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
305 và
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
306, người dùng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
305 đang theo dõi
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
308 và người dùng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
308 đang theo dõi
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
306. Dữ liệu đại diện cho ở trên là đây

follower_idfollowed_id12142334

Cuối cùng, bảng bài đăng chứa một bài đăng từ mỗi người dùng

idtextuser_id1post từ susan22 post từ mary33post từ david44post từ john 1

Bảng này cũng bỏ qua một số trường không phải là một phần của cuộc thảo luận này

Đây là cuộc gọi

user1.followed.remove(user2)
79 mà tôi đã xác định lại cho truy vấn này một lần nữa

user1.followed.remove(user2)
6

Tôi đang gọi thao tác nối trên bảng bài viết. Đối số đầu tiên là bảng liên kết người theo dõi và đối số thứ hai là điều kiện tham gia. Điều tôi muốn nói với cuộc gọi này là tôi muốn cơ sở dữ liệu tạo một bảng tạm thời kết hợp dữ liệu từ các bảng bài đăng và người theo dõi. Dữ liệu sẽ được hợp nhất theo điều kiện mà tôi đã chuyển làm đối số

Điều kiện mà tôi đã sử dụng nói rằng trường

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e
        self.A = A("yo", 2, 6)

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ling = B(5, 9)

print ling.addAllNums() 
26 của bảng người theo dõi phải bằng với trường
user1.followed.remove(user2)
3 của bảng bài đăng. Để thực hiện việc hợp nhất này, cơ sở dữ liệu sẽ lấy từng bản ghi từ bảng bài đăng (phía bên trái của phép nối) và nối thêm bất kỳ bản ghi nào từ bảng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
00 (phía bên phải của phép nối) khớp với điều kiện. Nếu nhiều bản ghi trong
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
00 phù hợp với điều kiện, thì mục đăng sẽ được lặp lại cho mỗi. Nếu đối với một bài đăng nhất định không có người theo dõi trùng khớp, thì bản ghi bài đăng đó không phải là một phần của tham gia

Với dữ liệu ví dụ tôi đã xác định ở trên, kết quả của thao tác nối là

idtextuser_idfollower_idfollowed_id1bài đăng từ susan2122bài đăng từ mary3233bài đăng từ david4143bài đăng từ david434

Lưu ý cách các cột

user1.followed.remove(user2)
3 và
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e
        self.A = A("yo", 2, 6)

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ling = B(5, 9)

print ling.addAllNums() 
26 bằng nhau trong mọi trường hợp, vì đây là điều kiện nối. Bài đăng từ người dùng
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
304 không xuất hiện trong bảng đã tham gia vì không có mục nào trong số người theo dõi có
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
304 là người dùng được theo dõi hoặc nói cách khác, không có ai theo dõi john. Và bài đăng từ
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
306 xuất hiện hai lần, bởi vì người dùng đó được theo dõi bởi hai người dùng khác nhau

Có thể không rõ ràng ngay lập tức tôi sẽ thu được gì khi tạo liên kết này, nhưng hãy tiếp tục đọc, vì đây chỉ là một phần của truy vấn lớn hơn

bộ lọc

Hoạt động tham gia đã cho tôi một danh sách tất cả các bài đăng được theo dõi bởi một số người dùng, đó là nhiều dữ liệu hơn mà tôi thực sự muốn. Tôi chỉ quan tâm đến một tập hợp con của danh sách này, các bài đăng được theo sau bởi một người dùng, vì vậy tôi cần cắt bỏ tất cả các mục nhập mà tôi không cần, điều mà tôi có thể thực hiện với lệnh gọi

user1.followed.remove(user2)
68

Đây là phần bộ lọc của truy vấn

user1.followed.remove(user2)
7

Vì truy vấn này nằm trong một phương thức của lớp

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04, nên biểu thức
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
323 đề cập đến ID người dùng của người dùng mà tôi quan tâm. Cuộc gọi
user1.followed.remove(user2)
68 chọn các mục trong bảng đã tham gia có cột
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e):
        self.d = d
        self.e = e
        self.A = A("yo", 2, 6)

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ling = B(5, 9)

print ling.addAllNums() 
21 được đặt cho người dùng này, nói cách khác có nghĩa là tôi chỉ giữ các mục có người dùng này là người theo dõi

Giả sử người dùng mà tôi quan tâm là

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
304, có trường
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
327 được đặt thành 1. Đây là cách bảng đã tham gia trông sau quá trình lọc

idtextuser_idfollower_idfollowed_id1bài đăng từ susan2123bài đăng từ david414

Và đây chính xác là những bài viết mà tôi muốn

Hãy nhớ rằng truy vấn đã được đưa ra trên lớp

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
328, vì vậy mặc dù tôi đã kết thúc với một bảng tạm thời do cơ sở dữ liệu tạo ra như một phần của truy vấn này, nhưng kết quả sẽ là các bài đăng được đưa vào bảng tạm thời này mà không cần thêm

Sắp xếp

Bước cuối cùng của quy trình là sắp xếp kết quả. Một phần của truy vấn thực hiện điều đó cho biết

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
30

Ở đây tôi đang nói rằng tôi muốn kết quả được sắp xếp theo trường dấu thời gian của bài đăng theo thứ tự giảm dần. Với thứ tự này, kết quả đầu tiên sẽ là bài đăng blog gần đây nhất

Kết hợp bài viết sở hữu và theo dõi

Truy vấn mà tôi đang sử dụng trong hàm

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
329 cực kỳ hữu ích nhưng có một hạn chế. Mọi người mong muốn thấy các bài đăng của chính họ được đưa vào dòng thời gian của những người dùng được theo dõi và truy vấn vì nó không có khả năng đó

Có hai cách khả thi để mở rộng truy vấn này để bao gồm các bài đăng của chính người dùng. Cách đơn giản nhất là để nguyên truy vấn nhưng đảm bảo rằng tất cả người dùng đang theo dõi chính họ. Nếu bạn là người theo dõi của chính mình, thì truy vấn như hình trên sẽ tìm thấy bài đăng của chính bạn cùng với bài đăng của tất cả những người bạn theo dõi. Nhược điểm của phương pháp này là nó ảnh hưởng đến số liệu thống kê về người theo dõi. Tất cả số lượng người theo dõi sẽ tăng lên theo từng người, vì vậy chúng sẽ phải được điều chỉnh trước khi chúng được hiển thị. Cách thứ hai để làm điều này là tạo một truy vấn thứ hai trả về các bài đăng của chính người dùng, sau đó sử dụng toán tử "union" để kết hợp hai truy vấn thành một truy vấn duy nhất

Sau khi xem xét cả hai lựa chọn, tôi quyết định chọn cái thứ hai. Bên dưới, bạn có thể thấy chức năng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
329 sau khi nó được mở rộng để bao gồm các bài đăng của người dùng thông qua liên kết

ứng dụng/mô hình. py. Truy vấn bài đăng được theo dõi với bài đăng của chính người dùng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
31

Lưu ý cách các truy vấn

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
06 và
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
332 được kết hợp thành một, trước khi áp dụng sắp xếp

Đơn vị kiểm tra mô hình người dùng

Mặc dù tôi không xem xét việc triển khai người theo dõi nhưng tôi đã xây dựng một tính năng "phức tạp", tôi nghĩ nó cũng không tầm thường. Mối quan tâm của tôi khi viết mã không tầm thường là đảm bảo rằng mã này sẽ tiếp tục hoạt động trong tương lai, khi tôi thực hiện các sửa đổi trên các phần khác nhau của ứng dụng. Cách tốt nhất để đảm bảo rằng mã bạn đã viết tiếp tục hoạt động trong tương lai là tạo một bộ kiểm tra tự động mà bạn có thể chạy lại mỗi khi thay đổi được thực hiện

Python bao gồm gói

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
333 rất hữu ích giúp dễ dàng viết và thực hiện các bài kiểm tra đơn vị. Hãy viết một số bài kiểm tra đơn vị cho các phương thức hiện có trong lớp
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
04 trong bài kiểm tra. mô-đun py

kiểm tra. py. Kiểm tra đơn vị mô hình người dùng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
32

Tôi đã thêm bốn bài kiểm tra thực hiện chức năng băm mật khẩu, hình đại diện người dùng và người theo dõi trong mô hình người dùng. Các phương pháp

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
335 và
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
336 là các phương pháp đặc biệt mà khung kiểm tra đơn vị thực hiện trước và sau mỗi lần kiểm tra tương ứng

Tôi đã thực hiện một hack nhỏ để ngăn các bài kiểm tra đơn vị sử dụng cơ sở dữ liệu thông thường mà tôi sử dụng để phát triển. Bằng cách đặt biến môi trường

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
337 thành
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
338, tôi thay đổi cấu hình ứng dụng để hướng SQLAlchemy sử dụng cơ sở dữ liệu SQLite trong bộ nhớ trong quá trình kiểm tra

Phương thức

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
335 sau đó tạo ngữ cảnh ứng dụng và đẩy nó. Điều này đảm bảo rằng phiên bản ứng dụng Flask, cùng với dữ liệu cấu hình của nó có thể truy cập được đối với các tiện ích mở rộng Flask. Đừng lo lắng nếu điều này không có nhiều ý nghĩa vào thời điểm này, vì điều này sẽ được đề cập chi tiết hơn sau

Cuộc gọi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
340 tạo tất cả các bảng cơ sở dữ liệu. Đây là một cách nhanh chóng để tạo cơ sở dữ liệu từ đầu, hữu ích cho việc thử nghiệm. Để sử dụng cho phát triển và sản xuất, tôi đã chỉ cho bạn cách tạo các bảng cơ sở dữ liệu thông qua di chuyển cơ sở dữ liệu

Bạn có thể chạy toàn bộ bộ thử nghiệm bằng lệnh sau

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
33

Từ giờ trở đi, mỗi khi có thay đổi đối với ứng dụng, bạn có thể chạy lại các bài kiểm tra để đảm bảo các tính năng đang được kiểm tra không bị ảnh hưởng. Ngoài ra, mỗi khi một tính năng khác được thêm vào ứng dụng, một bài kiểm tra đơn vị sẽ được viết cho nó

Tích hợp Người theo dõi với Ứng dụng

Sự hỗ trợ của những người theo dõi trong cơ sở dữ liệu và các mô hình hiện đã hoàn tất, nhưng tôi không có bất kỳ chức năng nào trong số này được tích hợp vào ứng dụng, vì vậy tôi sẽ thêm chức năng đó ngay bây giờ

Bởi vì các hành động theo dõi và hủy theo dõi đưa ra các thay đổi trong ứng dụng, tôi sẽ triển khai chúng dưới dạng yêu cầu

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
341, được kích hoạt từ trình duyệt web do gửi biểu mẫu web. Sẽ dễ dàng hơn khi triển khai các tuyến này dưới dạng yêu cầu
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
342, nhưng sau đó chúng có thể bị khai thác trong các cuộc tấn công CSRF. Bởi vì các yêu cầu
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
342 khó bảo vệ hơn trước CSRF, chúng chỉ nên được sử dụng cho các hành động không đưa ra thay đổi trạng thái. Việc triển khai những điều này là kết quả của việc gửi biểu mẫu sẽ tốt hơn vì sau đó mã thông báo CSRF có thể được thêm vào biểu mẫu

Nhưng làm cách nào để kích hoạt hành động theo dõi hoặc hủy theo dõi từ biểu mẫu web khi điều duy nhất người dùng cần làm là nhấp vào "Theo dõi" hoặc "Hủy theo dõi" mà không gửi bất kỳ dữ liệu nào? . Các yếu tố duy nhất trong biểu mẫu sẽ là mã thông báo CSRF, được triển khai dưới dạng trường ẩn và được Flask-WTF tự động thêm vào và nút gửi, đây sẽ là thứ người dùng cần nhấp để kích hoạt hành động. Vì hai hành động gần như giống hệt nhau nên tôi sẽ sử dụng cùng một biểu mẫu cho cả hai. Tôi sẽ gọi biểu mẫu này là

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
344

ứng dụng/biểu mẫu. py. Biểu mẫu trống để theo dõi và hủy theo dõi

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
34

Hãy thêm hai tuyến đường mới trong ứng dụng để theo dõi và hủy theo dõi người dùng

ứng dụng/tuyến đường. py. Theo dõi và hủy theo dõi các tuyến đường

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
35

Việc xử lý biểu mẫu trong các route này đơn giản hơn vì chúng ta chỉ phải thực hiện phần gửi. Không giống như các biểu mẫu khác như biểu mẫu đăng nhập và chỉnh sửa hồ sơ, hai biểu mẫu này không có trang riêng, các biểu mẫu sẽ được hiển thị theo tuyến đường

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
345 và sẽ xuất hiện trong trang hồ sơ của người dùng. Lý do duy nhất khiến cuộc gọi
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
346 có thể thất bại là nếu mã thông báo CSRF bị thiếu hoặc không hợp lệ, vì vậy trong trường hợp đó, tôi chỉ cần chuyển hướng ứng dụng trở lại trang chủ

Nếu quá trình xác thực biểu mẫu thành công, tôi sẽ thực hiện một số kiểm tra lỗi trước khi thực sự thực hiện hành động theo dõi hoặc hủy theo dõi. Điều này là để ngăn chặn các sự cố không mong muốn và cố gắng cung cấp một thông báo hữu ích cho người dùng khi xảy ra sự cố

Để hiển thị nút theo dõi hoặc hủy theo dõi, tôi cần khởi tạo một đối tượng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
344 và chuyển nó cho người dùng. mẫu html. Vì hai hành động này loại trừ lẫn nhau nên tôi có thể chuyển một phiên bản duy nhất của biểu mẫu chung này sang mẫu

ứng dụng/tuyến đường. py. Theo dõi và hủy theo dõi các tuyến đường

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
36

Bây giờ tôi có thể thêm các biểu mẫu theo dõi hoặc hủy theo dõi trong trang hồ sơ của mỗi người dùng

ứng dụng/mẫu/người dùng. html. Theo dõi và hủy theo dõi các liên kết trong trang hồ sơ người dùng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
37

Các thay đổi đối với mẫu hồ sơ người dùng thêm một dòng bên dưới dấu thời gian được nhìn thấy lần cuối cho biết số lượng người theo dõi và người dùng được theo dõi mà người dùng này có. Và dòng có liên kết "Chỉnh sửa" khi bạn đang xem hồ sơ của chính mình bây giờ có thể có một trong ba liên kết có thể

  • Nếu người dùng đang xem hồ sơ của chính họ, liên kết "Chỉnh sửa" sẽ hiển thị như trước
  • Nếu người dùng đang xem một người dùng hiện không được theo dõi, biểu mẫu "Theo dõi" sẽ hiển thị
  • Nếu người dùng đang xem một người dùng hiện đang được theo dõi, biểu mẫu "Hủy theo dõi" sẽ hiển thị

Để sử dụng lại phiên bản

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
348 cho cả biểu mẫu theo dõi và hủy theo dõi, tôi chuyển đối số
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
349 khi hiển thị nút gửi. Trong nút gửi thì thuộc tính
class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
349 xác định nhãn nên với thủ thuật này mình có thể thay đổi nội dung trong nút gửi tùy theo thao tác mà mình cần trình bày với người dùng

Tại thời điểm này, bạn có thể chạy ứng dụng, tạo một vài người dùng và chơi với những người dùng theo dõi và hủy theo dõi. Điều duy nhất bạn cần nhớ là nhập URL trang hồ sơ của người dùng mà bạn muốn theo dõi hoặc hủy theo dõi, vì hiện tại không có cách nào để xem danh sách người dùng. Ví dụ: nếu bạn muốn theo dõi người dùng có tên người dùng

class A(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def addNums():
        self.b + self.c

class B(object):
    def __init__(self, d, e, A):
        self.d = d
        self.e = e
        self.A = A

    def addAllNums(self):
        x = self.d + self.e + self.A.b + self.A.c
        return x

ting = A("yo", 2, 6)
ling = B(5, 9, ting)

print ling.addAllNums()
305, bạn cần nhập http. //máy chủ cục bộ. 5000/user/susan trên thanh địa chỉ của trình duyệt để truy cập trang hồ sơ của người dùng đó. Đảm bảo bạn kiểm tra số lượng người dùng được theo dõi và người theo dõi thay đổi như thế nào khi bạn thực hiện theo dõi hoặc hủy theo dõi

Lẽ ra tôi nên hiển thị danh sách các bài đăng được theo dõi trong trang chỉ mục của ứng dụng, nhưng tôi chưa có sẵn tất cả các phần để làm điều đó, vì người dùng chưa thể viết bài đăng trên blog. Vì vậy, tôi sẽ trì hoãn thay đổi này cho đến khi có chức năng đó

Xin chào và cảm ơn bạn đã ghé thăm blog của tôi. Nếu bạn thích bài viết này, vui lòng xem xét hỗ trợ công việc của tôi trên blog này trên Patreon