<aside> 📌 시스템 분석과 데이터베이스 설계는 이미 완성된 상태에서 진행
</aside>
Django REST framework 튜토리얼 완료 후 API 제작 연습하기
[MySQL] 스터디카페 관리시스템 개발 (4) 시스템 구현 및 운영
# rental\\models.py
class Student(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
residual_time = models.IntegerField(default=0)
class Ticket(models.Model):
time = models.IntegerField()
storable = models.BooleanField()
price = models.IntegerField()
student = models.ManyToManyField(Student, through='Purchase')
class Purchase(models.Model):
student = models.ForeignKey(Student, related_name='purchase', on_delete=models.CASCADE)
ticket = models.ForeignKey(Ticket, related_name='purchase', on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
class Seat(models.Model):
student = models.ManyToManyField(Student, through='Rent')
class Rent(models.Model):
student = models.ForeignKey(Student, related_name='rent', on_delete=models.CASCADE)
seat = models.ForeignKey(Seat, related_name='rent', on_delete=models.CASCADE)
start_date = models.DateTimeField(auto_now_add=True)
real_end_date = models.DateTimeField(blank=True)
expected_end_date = models.DateTimeField() # blank=True?
max_length
를 넉넉히 설정했다.~~on_delete=models.SET_NULL
: 학생이나 이용권이 삭제 돼도 총수익, 자리의 대여기록을 남기기 위해서는 행을 지우면 안된다.~~DRF Serializer에서 ManyToManyField 구현 → 평소에 접근하는 방향에 따라 결정!
연결된 한쪽 방향으로 Field를 정의한다.
Django Model 구현하듯 Associative Entity에 외래키 두 개 포함시킨다.
고민
.save()
오버라이딩perform_[actions]()
오버라이딩@receiver
이용expected_end_date
필드에서 blank & null 속성null=True
, blank=True
현재시각으로 초기화하는 방법도 있는데, 이 경우와 같은 방식으로 구현한다.
우선 rent 객체를 생성할 때는 필드값을 비워놓고, trigger나 view에서 ORM을 실행하여 올바른 값을 할당한다.
RentListView class의 perform_create()
메서드에서 serializer.save()
이후에 expected_end_date
필드에 값을 할당한다.
from django.utils import timezone
class RentListView(generics.ListCreateAPIView):
(... 생략 ...)
def perform_create(self, serializer):
serializer.save(student=self.request.user.student)
rent = serializer.instance
rent.expected_end_date = rent.start_date + /
timezone.timedelta(seconds=rent.student.residual_time)
@receiver
데코레이터를 이용하여 post_save
signal에 대한 trigger를 정의
from django.utils import timezone
@receiver(post_save, sender=Rent)
def compute_expected_end_date(sender, instance, created, **kwargs):
if created:
instance.expected_end_date = instance.start_date + /
timezone.timedelta(seconds=instance.student.residual_time)
instance.save()
null=False
, blank=False
(default)rent 객체가 save되기 전에 필드에 값을 전달한다. 쿼리 실행 지연으로 인해 start_date
와 현재시각이 다를 수 있다(?)
RentListView class의 perform_create()
메서드에서 serializer.save()
이전에 student
와 함께expected_end_date
필드에 값을 할당한다.
from django.utils import timezone
class RentListView(generics.ListCreateAPIView):
(... 생략 ...)
def perform_create(self, serializer):
student = self.request.user.student
exp_end_date = timezone.now() + timezone.timedelta(seconds=student.residual_time)
serializer.save(student=student, expected_end_date=exp_end_date)
pre_save
signal 관련 질문
created
매개변수가 없는데, update 쿼리에도 반응하는가?
update_fields
매개변수는 뭐지??
start_date
필드에 default로 할당되는 현재시각을 이용할 수는 없는가?
참고로, MySQL에서는 before insert
trigger를 이용했다.
# cal_expected_end_date 트리거
drop trigger if exists cal_expected_end_date;
create trigger cal_expected_end_date
before insert on Rent
for each row
set new.expected_end_date = date_add(new.start_date,
interval(select residual_time from Student where student_id = new.student_id) second);
storable 대여 중 storable 이용권 구매
storable 대여 중 instorable 이용권 구매
instorable 대여 중 storable 이용권 구매
instorable 대여 중 instorable 이용권 구매
문제상황) 저장 안되는 거 겁나 많이 사고 마지막에 저장되는 거 사면 전부 저장됨
아예 저장 안될 때는 안되는 것만,
가능할 때는 되는 것만 구매 가능?