ORM은 객체간의 관계를 바탕으로 자동으로 테이블을 생성해주고 SQL문을 사용하지 않고 사용하는 언어 그대로 클래스의 메서드를 통해 데이터베이스 조작(CRUD)을 할 수 있게 해주는 기능입니다.
ORM(Object-Relational Mapping)
장고에서
models.py에 정의한 모델을 바탕으로 객체간의 관계를 통해 데이터베이스의 테이블을 자동으로 생성해줍니다. 이때 하나의 class는 하나의 테이블을 생성하고 관계에 따라 스루테이블이 생기기도 합니다. CRUD를 할 때 SQL 쿼리를 사용하지 않고 데이터를 다룰 수 있습니다. ORM을 통해 CRUD기능을 구현할 때 SQL 쿼리를 사용하지 않고 데이터를 다룰 수 있습니다.
객체를 통해 간접적으로 데이터베이스 데이터를 다룹니다.
장점:
현재 쓰는 언어만 사용해도 됨
해당 언어에서 지원하는 라이브러리 사용 가능
DBMS 종속성이 왜 줄어들지??
단점:
N+1 쿼리 이슈
django ORM은 Lazy-Loading 방식
모든 명령 처리가 끝나고 실제로 데이터를 불러와야 할 시점이 왔을 때 데이터베이스에 쿼리를 실행하는 방식
데이터베이스 복잡도를 데이터베이스 시스템에서 어플리케이션 코드로 옮기게 됨.
https://landwhale2.github.io/python/10/
https://gggggeun.tistory.com/75
결국 SQL문을 써야할 수도 있다
>>> queryset = Book.objects.all()
>>> str(queryset.query)
SELECT "appname_book"."id", "appname_book"."title","appname_book"."author"
FROM "appname_book"
from django.db.models import Q
queryset = Book.objects.filter(Q(title="A") | Q(title="B"))
queryset = Book.objects.filter(Q(title="A") & Q(title="B"))
queryset = Book.objects.filter(~Q(title="A"))
queryset = Book.objects.filter(title="A")| Book.objects.filter(title="B")
queryset = Book.objects.filter(title="A", title="B")
queryset = Book.objects.filter(title="A") & Book.objects.filter(title="B")
# 내장함수 사용
queryset = Book.objects.exclude(title="A")
메타 데이터를 읽어서 사이트 컨텐츠를 관리할 수 있도록하는 모델 중심의 인터페이스
https://django-doc-test-kor.readthedocs.io/en/old_master/topics/templates.html#template-inheritance
https://docs.djangoproject.com/en/4.1/topics/templates/
{% extends "base.html" %}
태그가 하는 일은 템플릿 엔진에게 태그의 내용을 할 것이라고 알려주는 것
Django template engine is used to separate the design from the python code and allows us to build dynamic web pages.
A Django template is a text document or a Python string marked-up using the Django template language. Some constructs are recognized and interpreted by the template engine.
Django 개발 가이드라인은 "App폴더/templates/App명/템플릿파일" 처럼, 각 App 폴더 밑에 templates 서브폴더를 만들고 다시 그 안에 App명을 사용하여 서브폴더를 만든 후 템플릿 파일을 그 안에 넣기를 권장한다
def solution(lottos, win_nums):
pos_nums=set(win_nums)-set(lottos) # 당첨 가능한 숫자
inter_nums=set(win_nums)&set(lottos) # 당첨된 숫자
zero_cnt=lottos.count(0) # 0의 갯수
if zero_cnt>=len(pos_nums):
highest=len(inter_nums)+len(pos_nums)
lowest=len(inter_nums)
else:
highest=len(inter_nums)+zero_cnt
lowest=len(inter_nums)
if highest==0:
lowest,highest=1,1
elif lowest==0:
lowest=1
return [6-highest+1,6-lowest+1]
당첨 가능한 숫자, 당첨된 숫자, 순위를 결정하는 0의 갯수를 변수로 만들어놓고
0의 갯수와 거기에 들어갈 수 있는 당첨 가능한 숫자의 갯수를 비교해서
최고점이 0이면 최저점도 당연히 0이 되기때문에 최고점이 0인경우 점수가 1인 것과 같은 결과가 나와야하므로 점수 변수에 1을 넣어준다
최저점은 언제나 0이 하나도 맞지 않고 이미 당첨된 숫자만 맞는 경우이므로 두번 계산해줄 필요도 없고, len(inter_nums)와 같은 값이라서 레퍼런스를 여러개 만들 필요가 없을 것 같아서 수정했다
그리고 0의 갯수가 당첨 가능한 숫자 리스트의 길이보다 항상 작거나 같기때문에 비교하는 게 아무 의미가 없었다...............갹
def solution(lottos, win_nums):
inter_nums=set(win_nums)&set(lottos)
zero_cnt=lottos.count(0)
lowest=len(inter_nums)
highest=lowest+zero_cnt
if highest==0:
lowest,highest=1,1
elif lowest==0:
lowest=1
return [6-highest+1,6-lowest+1]
def solution(lottos, win_nums):
rank=[6,6,5,4,3,2,1]
cnt_0 = lottos.count(0)
ans = 0
for x in win_nums:
if x in lottos:
ans += 1
return rank[cnt_0 + ans],rank[ans]
단순히 맞으면 된다고 생각하고 짜야되는데 너무 복잡하게 생각한 것 같당.. 랭크도 어차피 6개 밖에 안되고 로또나 당첨번호나 다 6자리라서 for문 돌려도 상관없고 해서 진짜 잘푼 것 같다ㅜㅜ
def solution(lottos, win_nums):
rank = {
0: 6,
1: 6,
2: 5,
3: 4,
4: 3,
5: 2,
6: 1
}
return [rank[len(set(lottos) & set(win_nums)) + lottos.count(0)], rank[len(set(lottos) & set(win_nums))]]
같은 set을 써도.. 나도 이렇게 써야지ㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣ
def solution(number, limit, power):
answer=[]
for i in range(1,number+1):
cnt=0
for j in range(1,int(i**0.5)+1):
if i%j==0:
cnt+=1
if i**0.5==int(i**0.5):
cnt=(cnt-1)*2+1
else:
cnt=cnt*2
if cnt>limit:
cnt=power
answer.append(cnt)
return sum(answer)
챠챠챠
if i**0.5==int(i**0.5):
이 부분 if (j == i**2):
이렇게 해도 됨 더 간단함
그리고 answer에 append하지 않고 첨부터 answer=0으로 선언해서 해서 아예 처음부터 계속 더하는 것도.. 어차피 더할거니까.. 근데 계속 값 바뀌면 안좋다해서 킁..
def cf(n): # 공약수 출력
a = []
for i in range(1,int(n**0.5)+1):
if n%i == 0:
a.append(n//i)
a.append(i)
return len(set(a))
def solution(number, limit, power):
return sum([cf(i) if cf(i)<=limit else power for i in range(1,number+1)])
공약수 갯수 구하는 부분을 공약수 전체 리스트를 구해서 그걸 set으로 중복을 없애고 길이를 구함