Có mô hình như sau (django)
# models.py - django
class Product(models.Model): # thêm các trường, chay migration database
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
def __str__(self):
return self.title
class Image(models.Model):
products = models.ForeignKey(Product, blank=True, null=True, on_delete=models.CASCADE, related_name="product_image") # sẽ tạo 1 cột products_id
image_name = models.ImageField(upload_to="product_images_gallery/", default="no_image.jpg")
alt_text = models.CharField(max_length=255,null=True,blank=True)
def __str__(self):
return self.products.title
Trong mô hình trên, lớp Image
là Gallery hình ảnh của lớp Product
. Nó có mối quan hệ Một-Nhiều: 1 sản phẩm có thể có nhiều hình ảnh. Khóa ngoại được đặt bên trong lớp Image
.
Xem thêm về Tạo models Thư viện hình ảnh cho sản phẩm trong Django
Theo mô hình trên, trong database sẽ có 2 bảng là product
và image
. Và để lưu dữ liệu vào 2 bảng trên trong 1 lần chạy Crawl và giữ mối liên quan với nhau thì sử dụng SQLAlchemy Relationship.
Trong mô hình SQLALchemy thiết lập như sau
#models.py - sqlalchemy
class Shop_Product(DeclarativeBase):
__tablename__ = "shop_product"
id = Column(Integer, primary_key=True)
slug = Column("slug", String, unique=True)
title = Column("title", String)
class Shop_Image(DeclarativeBase):
__tablename__ = "shop_image"
id = Column(Integer, primary_key=True)
image_name = Column("image_name", String)
products_id = Column(Integer, ForeignKey('shop_product.id'))
# relationship
products = relationship('Shop_Product', backref='image1') # image1 được sử dụng trong pipelines
Trong nhiều hướng dẫn về Relationship, họ không chỉ bạn phải làm gì trong pipelines.py
Tiếp theo tới tệp pipelines.py
# pipelines.py - scrapy
class SaveSpinderPipeline(object):
def __init__(self):
"""
Tạo kết nối với database
"""
engine = db_connect()
create_items_table(engine)
self.Session = sessionmaker(bind=engine)
def process_item(self, item, spider):
session = self.Session()
pro = Shop_Product()
img = Shop_Image()
pro.slug = item['slug']
pro.title = item['title']
img.image_name = item['image']
# kiểm tra xem hình ảnh đã tồn tại chưa
exist_img = session.query(Shop_Image).filter_by(image_name=img.image_name).first()
if exist_img is not None:
pro.image1 = exist_img
else:
pro.image1.append(img)
try:
session.add(pro)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return item
Trường hợp trên đây sử dụng khi bạn muốn lấy nhiều hình ảnh cho sản phẩm. Nếu bạn chỉ có cần hình ảnh cho 1 sản phẩm, hãy thêm trường
image
vàoclass Product
. Khi đó mọi thứ sẽ dễ dàng hơn.