DEV Community

Cover image for List Comprehension: ORM
Andrew Fuller
Andrew Fuller

Posted on

List Comprehension: ORM

Need a swift way to create lists when mapping object relations? List comprehensions are the way to go! You can easily connect all of our data in a programmatic way and manipulate it as you please. The example code below is for a one-to-many relationship between a Author, Book, and Contract.

class Book:

    all = []

    def __init__(self, title) -> None:
        self.title = title
        Book.all.append(self)

    def contracts(self):
        return [contract for contract in Contract.all if contract.book == self]

    def authors(self):
        return [contract.author for contract in self.contracts()]


    pass

Enter fullscreen mode Exit fullscreen mode

You will see repeatedly that list comprehensions are taken advantage of you algorithmically connect all of the objects and create usable lists out of them based simple criteria like: if this instance's attribute book is present or author in a list of objects.

class Author:

    all = []

    def __init__(self, name) -> None:
        self.name = name
        Author.all.append(self)

    def contracts(self):
        return [contract for contract in Contract.all if contract.author == self]

    def books(self): 
        return [contract.book for contract in self.contracts()]

    def sign_contract(self, book, date, royalties):
        return Contract(self, book, date, royalties)

    def total_royalties(self):
        return sum([contract.royalties for contract in self.contracts()])

    pass
Enter fullscreen mode Exit fullscreen mode

Again and again list comprehensions can be used simply to make accessible data from other classes in ORM. You can even use them in class methods to add more functionality like checking if a passed in date matches that of a book/author contract.

class Contract:

    all = []

    def __init__(self, author, book, date, royalties):
        self.author = author
        self.book = book
        self.date = date
        self.royalties = royalties
        Contract.all.append(self)

    @property
    def author(self):
        return self._author

    @author.setter
    def author(self, value):
        if not isinstance(value, Author):
            raise Exception
        self._author = value

    @property
    def book(self):
        return self._book

    @book.setter
    def book(self, value):
        if not isinstance(value, Book):
            raise Exception
        self._book = value

    @property
    def date(self):
        return self._date

    @date.setter
    def date(self, value):
        if not isinstance(value, str):
            raise Exception
        self._date = value

    @property
    def royalties(self):
        return self._royalties

    @royalties.setter
    def royalties(self, value):
        if not isinstance(value, int):
            raise Exception
        self._royalties = value

    @classmethod
    def contracts_by_date(cls, date):
        return [contract for contract in cls.all if contract.date == date]
Enter fullscreen mode Exit fullscreen mode

Overall, it is a very easy way of iterating through your data as opposed to creating 500 lines of code to associate what could be simple relations.

Top comments (0)