class OrderItem(db.Model): __tablename__ = 'order_items' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, index=True, nullable=False) slug = db.Column(db.String) price = db.Column(db.Integer, index=True, nullable=False) quantity = db.Column(db.Integer, index=True, nullable=False) order_id = db.Column(db.Integer, db.ForeignKey('orders.id'), nullable=False) order = relationship('Order', backref='order_items') product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False) product = relationship('Product', backref='order_items') user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) user = relationship('User', backref='products_bought') created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow) def get_summary(self): return { 'name': self.name, 'slug': self.slug, 'product_id': self.product_id, 'price': self.price, 'quantity': self.quantity }
class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password = db.Column(db.String(128)) first_name = db.Column(db.String(300), nullable=False) last_name = db.Column(db.String(300), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) # comments = db.relationship('Comment', foreign_keys='comment.user_id', backref='user', lazy='dynamic') roles = db.relationship('Role', secondary=users_roles, backref='users') def __repr__(self): return '<User {}>'.format(self.username) def is_password_valid(self, password): return bcrypt.check_password_hash(self.password, password) def is_admin(self): return 'ROLE_ADMIN' in [r.name for r in self.roles] def is_not_admin(self): return not self.is_admin()
class CategoryImage(FileUpload): category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=True) category = relationship('Category', backref='images') __mapper_args__ = { 'polymorphic_identity': 'CategoryImage' }
class ProductImage(FileUpload): product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=True) product = relationship('Product', backref='images') __mapper_args__ = { 'polymorphic_identity': 'ProductImage' }
class TagImage(FileUpload): tag_id = db.Column(db.Integer, db.ForeignKey('tags.id'), nullable=True) tag = relationship('Tag', backref='images') __mapper_args__ = { 'polymorphic_identity': 'TagImage' }
class UserRole(db.Model): __tablename__ = 'users_roles' user_id = db.Column(db.Integer, db.ForeignKey("users.id")) role_id = db.Column(db.Integer, db.ForeignKey("roles.id")) # users = db.relationship("User", foreign_keys=[user_id], backref='roles') user = db.relationship("User", foreign_keys=[user_id], backref='users_roles') role = db.relationship("Role", foreign_keys=[role_id], backref='users_roles') created_at = Column(db.DateTime, nullable=False, default=datetime.utcnow) __mapper_args__ = {'primary_key': [user_id, role_id]}
class Product(db.Model): __tablename__ = 'products' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), nullable=False) slug = db.Column(db.String, index=True, unique=True) description = db.Column(db.Text, nullable=False) price = db.Column(db.Integer, nullable=False) stock = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime(), default=datetime.utcnow, index=True, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) publish_on = db.Column(db.DateTime, index=True, default=datetime.utcnow) tags = relationship('Tag', secondary=products_tags, backref='products') categories = relationship('Category', secondary=products_categories, backref='products') comments = relationship('Comment', backref='product', lazy='dynamic') def __repr__(self): return '<Product %r>' % self.name def __str__(self): return '<Product {}>'.format(self.name) def get_summary(self): return { 'id': self.id, 'name': self.name, 'price': self.price, 'stock': self.stock, 'slug': self.slug, 'comments_count': self.comments.count(), 'tags': [{ 'id': t.id, 'name': t.name } for t in self.tags], 'categories': [{ 'id': c.id, 'name': c.name } for c in self.categories], 'image_urls': [i.file_path for i in self.images] }
class FileUpload(db.Model): __tablename__ = 'file_uploads' id = db.Column('id', db.Integer, primary_key=True) type = db.Column('type', db.String(15)) # this will be our discriminator file_path = db.Column(db.String, nullable=False) file_name = db.Column(db.String, nullable=False) file_size = db.Column(db.Integer, nullable=False) original_name = db.Column(db.String, nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) __mapper_args__ = { 'polymorphic_on': type, 'polymorphic_identity': 'FileUpload' }
class Category(db.Model): __tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255)) slug = db.Column(db.String(255), index=True, unique=True) description = db.Column(db.String()) created_at = db.Column(db.DateTime(), default=datetime.utcnow, index=True) updated_at = db.Column(db.DateTime()) def get_summary(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'image_urls': [image.file_path.replace('\\', '/') for image in self.images] } def __repr__(self): return self.name
class Order(db.Model): __tablename__ = 'orders' id = db.Column(db.Integer, primary_key=True) # order_status = db.Column(ColIntEnum(OrderStatus), default=OrderStatus.text) order_status = db.Column(db.Integer) tracking_number = db.Column(db.String) address_id = db.Column(db.Integer, db.ForeignKey('addresses.id'), nullable=False) address = relationship('Address', backref='orders', lazy=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) user = relationship('User', backref='orders') created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) def get_summary(self, include_order_items=False): dto = { 'id': self.id, 'order_status': ORDER_STATUS[self.order_status], 'tracking_number': self.tracking_number, # Please notice how we retrieve the count, through len(), instead of count() # as we did in Product.get_summary() for comments, why? we declared the association in different places 'address': self.address.get_summary() } if include_order_items: dto['order_items'] = [] for oi in self.order_items: dto['order_items'].append(oi.get_summary()) else: dto['order_items_count'] = len(self.order_items) return dto
__tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255)) slug = db.Column(db.String(255), index=True, unique=True) description = db.Column(db.String()) created_at = db.Column(db.DateTime(), default=datetime.utcnow, index=True) updated_at = db.Column(db.DateTime()) def get_summary(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'image_urls': [image.file_path.replace('\\', '/') for image in self.images] } def __repr__(self): return self.name @event.listens_for(Category.name, 'set') def receive_set(target, value, oldvalue, initiator): target.slug = slugify(unicode(value)) products_categories = \ db.Table("products_categories", db.Column("category_id", db.Integer, db.ForeignKey("categories.id")), db.Column("product_id", db.Integer, db.ForeignKey("products.id")))
class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True, nullable=False) description = db.Column(db.String(100), nullable=True)
__tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True, nullable=False) description = db.Column(db.String(100), nullable=True) class UserRole(db.Model): __tablename__ = 'users_roles' user_id = db.Column(db.Integer, db.ForeignKey("users.id")) role_id = db.Column(db.Integer, db.ForeignKey("roles.id")) # users = db.relationship("User", foreign_keys=[user_id], backref='roles') user = db.relationship("User", foreign_keys=[user_id], backref='users_roles') role = db.relationship("Role", foreign_keys=[role_id], backref='users_roles') created_at = Column(db.DateTime, nullable=False, default=datetime.utcnow) __mapper_args__ = {'primary_key': [user_id, role_id]} users_roles = db.Table('users_roles', db.Column('user_id', db.Integer, db.ForeignKey('users.id')), db.Column('role_id', db.Integer, db.ForeignKey('roles.id')), keep_existing=True)
class Address(db.Model): __tablename__ = 'addresses' id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String, nullable=False) last_name = db.Column(db.String, nullable=False) city = db.Column(db.String, nullable=False) country = db.Column(db.String, nullable=False) zip_code = db.Column(db.String, nullable=False) street_address = db.Column(db.String, nullable=False) phone_number = db.Column( db.String, nullable=True) # nullable because I have not implemented it user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) user = relationship('User', backref='addresses') created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) def get_summary(self, include_user=False): data = { 'id': self.id, 'first_name': self.first_name, 'last_name': self.last_name, 'address': self.street_address, 'zip_code': self.zip_code, 'city': self.city, 'country': self.country, 'created_at': self.created_at, 'updated_at': self.updated_at } if include_user: data['user'] = {'id': self.user_id, 'username': self.user.username} return data
@event.listens_for(Tag.name, 'set') def receive_set(target, value, oldvalue, initiator): target.slug = slugify(unicode(value)) class ProductTag(db.Model): __tablename__ = 'products_tags' product_id = Column(Integer, ForeignKey("products.id"), nullable=False) tag_id = Column(Integer, ForeignKey("tags.id"), nullable=False) product = db.relationship("Product", foreign_keys=[product_id], backref='product_tags') tag = db.relationship("Tag", foreign_keys=[tag_id], backref='product_tags') __mapper_args__ = {'primary_key': [product_id, tag_id]} __table_args__ = (UniqueConstraint('product_id', 'tag_id', name='same_tag_for_same_product'), ) products_tags = db.Table('products_tags', db.Column('product_id', db.Integer, db.ForeignKey('products.id')), db.Column('tag_id', db.Integer, db.ForeignKey('tags.id')), keep_existing=True)