-
Notifications
You must be signed in to change notification settings - Fork 1
/
models.py
137 lines (112 loc) · 4.55 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""
models.py, this module contains class declaration for all the
database entities that are used in the app
"""
from typing import List, Optional
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import ForeignKey, func, select, String, Integer, BigInteger
from sqlalchemy.orm import DeclarativeBase, column_property, Mapped, mapped_column, relationship
from flask_login import UserMixin
class Base(DeclarativeBase): # pylint: disable=too-few-public-methods
"""
The Base class that holds the metadata/schema for the database
"""
pass
class User(Base, UserMixin): # pylint: disable=too-few-public-methods
"""
The User class whose object represents a user of app, user_account table
"""
__tablename__ = "user_account"
username: Mapped[str] = mapped_column(String(30), primary_key=True)
fullname: Mapped[str] = mapped_column(String(50), nullable=False)
email: Mapped[str] = mapped_column(String(256), nullable=False, unique=True)
password: Mapped[str] = mapped_column(String(300), nullable=False)
profile_pic_url: Mapped[Optional[str]] = mapped_column(String(400), default="user.png")
posts: Mapped[List["Posts"]] = relationship(back_populates="owner")
def __str__(self) -> str:
return (
f"\nUsername: {self.username}"
f"\nEmail: {self.email}"
f"\nPassword: {self.password}"
f"\nName: {self.fullname}"
f"\nProfile pic: {self.username}"
)
def get_id(self):
return self.username
def is_moderator(self):
if "<Mod>" in self.fullname:
return True
else:
return False
def promote_to_moderator(self):
if " <Mod>" in self.fullname:
return True
else:
self.fullname += " <Mod>"
return True
def demote_moderator(self):
if " <Mod>" in self.fullname:
self.fullname.replace(" <Mod>","")
return True
class Likes(Base): # pylint: disable=too-few-public-methods
"""
The Likes class whose object represents a Like for a post
"""
__tablename__ = "likes"
id: Mapped[int] = mapped_column(primary_key=True)
liked_post_id: Mapped[int] = mapped_column(ForeignKey("posts.id"))
post: Mapped["Posts"] = relationship(back_populates="likes")
liked_by_id: Mapped[str] = mapped_column(ForeignKey("user_account.username"))
user: Mapped["User"] = relationship()
def __str__(self):
return (
f"\nPost ID: {self.liked_post_id}"
f"\nLiked By: {self.liked_by_id}"
)
class Posts(Base): # pylint: disable=too-few-public-methods
"""
The Post class whose object represents a post made by the user
Can contain Title, text and optionally image
"""
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(256), nullable=False)
text: Mapped[str] = mapped_column(String(1000), nullable=False)
image: Mapped[Optional[str]] = mapped_column(String(400))
likes: Mapped[List["Likes"]] = relationship(back_populates="post")
timestamp: Mapped[int] = mapped_column(BigInteger, nullable=False)
owner_id: Mapped[str] = mapped_column(ForeignKey("user_account.username"))
owner: Mapped["User"] = relationship(back_populates="posts")
comments: Mapped[List["Comments"]] = relationship(back_populates="post")
no_of_likes = column_property(
select(func.count(Likes.id))
.where(Likes.liked_post_id == id)
.scalar_subquery()
)
def __str__(self) -> str:
return (
f"\nPost ID: {self.id}"
f"\nText: {self.text}"
f"\nImage: {self.image}"
f"\nLikes: {self.no_of_likes}"
f"\nTimestamp: {self.timestamp}"
)
class Comments(Base): # pylint: disable=too-few-public-methods
"""
The Comments class whose object represents a comment on a Post object
"""
__tablename__ = "comments"
id: Mapped[int] = mapped_column(primary_key=True)
text: Mapped[str] = mapped_column(String(500), nullable=False)
creator_id: Mapped[str] = mapped_column(ForeignKey("user_account.username"))
created_by: Mapped["User"] = relationship()
post_id: Mapped[int] = mapped_column(ForeignKey("posts.id"))
post: Mapped["Posts"] = relationship()
def __str__(self) -> str:
return (
f"\nComment ID: {self.id}"
f"\ntext: {self.text}"
f"\nPost ID: {self.post_id}"
)
# The db object which is used to access database
db = SQLAlchemy(model_class=Base)