Chi tiết thao tác trên bảng với ORM
Mục lục
- Chi tiết thao tác trên bảng với ORM
- Tructruong bang
- ORM thao tác CRUD
- Truy vấn liên bảng dựa trên quan hệ đối tượng
- Truy vấn liên bảng bằng dấu gạch ngang kép
- VD thao tác ORM
- ORM thao tác Cập nhật
- ORM thao tác Xoá
- ORM truy vấn (điểm nhấn)
- Truy vấn Chính và Truy vấn Ngược
- Tên liên quan cho truy vấn ngược
Tructruong bang
- Bang TacGia (tác giả)
- Bang ThongTinTacGia (thông tin tác giả)
- Bang NhaXuatBan (nhà xuất bản)
- Bang Sach (sách)
from django.db import models
class TacGia(models.Model):
ten = models.CharField(max_length=32, verbose_name='Tên tác giả')
tuoi = models.IntegerField(verbose_name='Tuổi')
thong_tin_tac_gia = models.OneToOneField(to='ThongTinTacGia', verbose_name='Thông tin chi tiết')
def __str__(self):
return self.ten
class ThongTinTacGia(models.Model):
ngay_sinh = models.DateField(verbose_name='Ngày sinh')
so_dien_thoai = models.CharField(max_length=32, verbose_name='Số điện thoại')
dia_chi = models.CharField(max_length=64, verbose_name='Địa chỉ')
def __str__(self):
return self.dia_chi
class NhaXuatBan(models.Model):
ten = models.CharField(max_length=32, verbose_name='Tên nhà xuất bản')
thanh_pho = models.CharField(max_length=32, verbose_name='Thành phố')
email = models.EmailField(verbose_name='Email')
def __str__(self):
return self.ten
class Sach(models.Model):
nid = models.AutoField(primary_key=True)
ten = models.CharField(max_length=32, verbose_name='Tên sách')
ngay_xuat_ban = models.DateField(verbose_name='Ngày xuất bản')
gia = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='Giá')
nha_xuat_ban = models.ForeignKey(to='NhaXuatBan', verbose_name='Nhà xuất bản')
tac_gia = models.ManyToManyField(to='TacGia', verbose_name='Tác giả')
def __str__(self):
return self.ten
ORM thao tác CRUD
Tạo (Create)
- Quan hệ một một
- Quan hệ một nhiều
- Quan hệ nhiều nhiều
# Tạo quan hệ một một
TacGia.objects.create(ten='Nguyễn Văn A', tuoi=30, thong_tin_tac_gia_id=1)
# Tạo quan hệ một nhiều
Sach.objects.create(ten='Cuốn sách đầu tiên', ngay_xuat_ban='2023-01-01', gia=100000, nha_xuat_ban_id=1)
# Tạo quan hệ nhiều nhiều
sach_obj = Sach.objects.get(nid=1)
sach_obj.tac_gia.add(1, 2)
Xoá (Delete)
# Xoá quan hệ một một
TacGia.objects.filter(nid=1).delete()
# Xoá quan hệ một nhiều
Sach.objects.filter(nid=1).delete()
# Xoá quan hệ nhiều nhiều
sach_obj = Sach.objects.get(nid=1)
sach_obj.tac_gia.remove(1, 2)
sach_obj.tac_gia.clear()
Cập nhật (Update)
# Cập nhật quan hệ một một
TacGia.objects.filter(nid=1).update(ten='Nguyễn Văn B', thong_tin_tac_gia_id=2)
# Cập nhật quan hệ một nhiều
Sach.objects.filter(nid=1).update(ten='Cuốn sách mới', nha_xuat_ban_id=2)
# Cập nhật quan hệ nhiều nhiều
sach_obj = Sach.objects.get(nid=1)
sach_obj.tac_gia.set([3, 4])
Truy vấn liên bảng dựa trên quan hệ đối tượng
- Truy vấn Chính và Truy vấn Ngược
# Truy vấn Chính
tac_gia_obj = TacGia.objects.get(ten='Nguyễn Văn A')
print(tac_gia_obj.thong_tin_tac_gia.so_dien_thoai) # In: 123456789
# Truy vấn Ngược
thong_tin_obj = ThongTinTacGia.objects.get(so_dien_thoai='123456789')
print(thong_tin_obj.tac_gia.ten) # In: Nguyễn Văn A
Truy vấn liên bảng bằng dấu gạch ngang kép
# Truy vấn Chính
TacGia.objects.filter(thong_tin_tac_gia__so_dien_thoai='123456789').values('ten')
# Truy vấn Ngược
ThongTinTacGia.objects.filter(tac_gia__ten='Nguyễn Văn A').values('so_dien_thoai', 'tac_gia__tuoi')
VD thao tác ORM
VD thao tác ORM (Nhấp để xem)
# Tạo mới
# Tạo quan hệ một một
thong_tin = ThongTinTacGia.objects.create(ngay_sinh='1990-01-01', so_dien_thoai='123456789', dia_chi='Hà Nội')
tac_gia = TacGia.objects.create(ten='Nguyễn Văn A', tuoi=33, thong_tin_tac_gia=thong_tin)
# Cập nhật
TacGia.objects.filter(nid=1).update(ten='Nguyễn Văn B', thong_tin_tac_gia_id=2)
# Xoá
TacGia.objects.filter(nid=1).delete()
Sach.objects.filter(nid=1).delete()
ORM truy vấn (điểm nhấn)
- Truy vấn Chính và Truy vấn Ngược
# Truy vấn Chính
Sach.objects.filter(ten='Cuốn sách đầu tiên').values('nha_xuat_ban__ten')
# Truy vấn Ngược
NhaXuatBan.objects.filter(sach__ten='Cuốn sách đầu tiên').values('ten')
Tên liên quan cho truy vấn ngược
related_name được sử dụng để đặt tên alias cho truy vấn ngược, giúp dễ dàng hơn khi gọi các phương thức truy vấn.