외래키를 사용하기위해 테이블을 2개 생성하고, 한 테이블에
models.ForeignKey
를 지정했다.
models
class Maker(models.Model):
mname = models.CharField(max_length=10)
mtel = models.CharField(max_length=20)
maddr = models.CharField(max_length=50)
class Meta:
ordering=('-id',)
def __str__(self):
return self.mname
class Product(models.Model):
pname = models.CharField(max_length=10)
pprice = models.IntegerField()
pmaker_name = models.ForeignKey(Maker,on_delete=models.CASCADE)
#외래키. Maker id PK 참조
def __str__(self): return self.mname
로 아래의 selector를 생성시켰다.
def List3(request):
mid = request.GET['id']
#where 조건 사용하여 테이블 검색
products = Product.objects.filter(pmaker_name=mid)
return render(request, 'list2.html',{'products':products,'pcount':len(products)})
models.py 생성시 직접 작성하지 않고 prompt에서 명령어로 생성한다.
python manage.py inspectdb > 이름.py
settings.py에서 명시한 DB 내용을 근거로 내용을 전부 찾아 .py파일로 자동작성한다.
생성된 .py파일에서 필요한 테이블 Class를 복사하여 models.py에 붙여넣는다.
생성된 .py는 삭제하고, 프로젝트를 Migration한다.
views.py
- 기존 데이터를 이용시 SQL문을 직접 사용하여 출력했다.
def ListFunc(request):
if request.method == 'GET':
#select : SQL문 사용
sql = "select * from sangdata"
conn = MySQLdb.connect(**config)
cursor = conn.cursor()
cursor.execute(sql)
datas = cursor.fetchall()
print(datas)
return render(request,'list.html',{'sangpums':datas})
else:
pass
django에서는 ORM 사용을 권장한다. 하지만 쿼리문이 복잡해질땐 부득이하게 SQL을 사용해야 할때가 있는데, 이때 반환되는 datas
의 타입의 튜플 속 튜플.
html에서 매핑하여 출력시 타입 쿼리셋과 다름을 유의해야한다. 아래 코드에서 인덱스로 튜플을 접근한 것을 확인했다.
{%for s in sangpums%}
<tr>
<td>{{s.0}}</td>
<td>{{s.1}}</td>
<td>{{s.2}}</td>
<td>{{s.3}}</td>
</tr>
{%endfor%}
이어서 이 리스트를 페이징처리로 변환해보자
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
장고에서는 페이징처리를 위해 위의 모듈을 지원한다.
위의 전체리스트 출력 객체 (datas)를 페이징 처리하는 코드이다.
#페이징 o
datas = Sangdata.objects.all().order_by("-code")
paginator = Paginator(object_list=datas,per_page=5)
try:
page = request.GET.get('page')
except:
page=1
try:
data = paginator.page(page)
except PageNotAnInteger: #페이지가 정수가 아닌 경우
data = paginator.page(1)
except EmptyPage: #비어있는경우
data = paginator.page(paginator.num_pages())
#개별 페이지 번호 표시용
allPage = range(paginator.num_pages+1)
print(allPage)
return render(request,'list.html',{'sangpums':data,'allpage':allPage})
개별 페이지 번호를 html에서 표시하기 위해 range로 수열을 만들어 넘겼다.
<!-- 페이징 -->
<tr>
<td colspan="5">
{% if sangpums.paginator.num_pages > 1 %}
<div>
{% for p in allpage %}
<!-- 현재페이지는 링크표시X -->
{% if p > 0 %}
{% if p == sangpums.number %}
[{{p}}]
{% elif p != sangpums.number %}
<a href="/sangpum/list?page={{p}}">[{{p}}]</a>
{% endif %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</td>
</tr>
html파일에서 페이징 처리 링크를 만드는 코드이다.
if sangpums.paginator.num_pages > 1
: 페이징처리 할 필요가 있는지에 대한 여부 확인for p in allpage
: range로 넘어온 페이지 수열의 사이즈를 for문으로 반복한다. range(1,4) : 1,2,3또다른 방법. 위의 방법과 같이 사용해도 된다.
<!-- 방법2 -->
{% if sangpums.has_previous %} <!-- 이전 페이지가 있는지 -->
<a href='/sangpum/list?page={{sangpums.previous_page_number}}'>«이전</a>
{% endif %}
{% if sangpums.has_next%} <!-- 다음 페이지가 있는지 -->
<a href='/sangpum/list?page={{sangpums.next_page_number}}'>다음»</a>
{% endif %}
<!-- 현재페이지 / 전체페이지-->
(페이지 : {{sangpums.number}} / {{sangpums.paginator.num_pages}})
previous/next_page_number
: 다음, 이전페이지 번호def InsertFunc(request):
if request.method == 'GET':
maxcode = Sangdata.objects.aggregate(Max('code'))['code__max']
return render(request,'insert.html',{'maxcode':maxcode+1})
elif request.method == 'POST':
#신상코드번호 유무 확인 후 insert반영
code = request.POST.get('code')
try:
Sangdata.objects.get(code=request.POST.get('code'))
return render(request, 'insert.html',{'msg':'이미 등록된 번호입니다'})
except:
Sangdata(
code = request.POST['code'],
sang = request.POST['sang'],
su = request.POST['su'],
dan = request.POST['dan']
).save()
return HttpResponseRedirect('/sangpum/list'
<script type="text/javascript">
function func(arg){
let result = confirm('code : '+arg +'번을 삭제할까요?')
if(result){
document.getElementById(arg).submit();
}else{
return;
}
}
</script>
<!-- 아이디마다 폼을 지정하기 위해 id를 code로 -->
<form action="/sangpum/delete" id="{{s.code}}" name="frm" method="get" style="display:inline;">
<input type="hidden" name="code" value="{{s.code}}">
<!-- a링크 기능없애고 func사용 -->
<a href="javascript:void(0); onclick=func({{s.code}})">삭제</a>
</form>
def DeleteFunc(request):
if request.method == 'GET':
upRec = Sangdata.objects.get(code=request.GET['code']) #기존 데이터 가져옴
upRec.delete()
return HttpResponseRedirect('/sangpum/list') #삭제 후 리스트로
else:
pass