티스토리 뷰

장고는 manytomanyfield를 제공하기 때문에 사용자가 매핑 테이블(중간 테이블)을 직접 만들지 않아도 되지만 직접 만들어보았다.

 

 

필드 사용과 미사용 시 비교됬던 부분

직접 매핑 테이블을 구현했을 때 

-  사용자가 직접 중간 테이블에서 서로의 id값을 넣어줘야 한다. (데이터가 많으면 관리가 어려울 것 같다)

- many to many field를 사용하지 않았기 때문에 매핑테이블로 직접 들어가서 정보를 가져와야한다.

장고에서 제공하는 many to many field를 사용했을 때

- 사용자가 중간 테이블을 이용하고 싶다면 through 옵션을 통해 직접 중간 테이블을 지정할 수 있다.

- 필드를 정의했기 때문에 참조 시 매핑 테이블을 들어가지않고 필드로 정의한 변수(?)를 통해 간접적으로 정보를 가져올 수 있다.

 

 

★ 참고  간단하게 서버에서 HTTP request를 할 수 있는 Httpie를 설치해주었다.

% pip install httpie

models.py 작성

피자와 토핑, 그리고 피자와 토핑을 이어주는 매핑 테이블을 만들어 각 클래스를 FK로 연결해줬다.

아래 코드에서는 related_name 이름을 다르게 작성하면 어떤 결과가 나오는지 확인차 다르게 작성했었다.

 

각 class 내부에 정의한 field와 파라미터의 종류는 mdn에서 더 많은 정보를 확인 할 수 있다.

# models.py
class Pizza(models.Model):
    dough = models.CharField(max_length=30)
    size = models.CharField(max_length=30)
    class Meta:
        db_table = 'Pizzas'

class Topping(models.Model):
    opsion1 = models.CharField(max_length=50)
    opsion2 = models.CharField(max_length=50)

    class Meta:
        db_table = 'toppings'

class Pizza_topping(models.Model): # related_name 을 다르게 설정해봤다.
		          # 'string으로 참조 클래스명을 적어주었지만 ''을 제외하고 적을수 있다.
                            # 단 class 자체를 먼저 작성해주어야한다.
    pizza = models.ForeignKey('Pizza',related_name='a', on_delete=models.CASCADE)
    topping = models.ForeignKey('Topping',related_name='b', on_delete=models.CASCADE)

    class Meta:
        db_table = 'pizza_topping'

python3 shell에서 데이터 기입

makemigration/migrate 실행하여 데이터 테이블을 만들어주고, 각 테이블에 직접 데이터를 넣어 주었는데, manytomanyfield를 사용하지 않았기 때문에 매핑(중간) 테이블에 피자와 토핑의 id 값을 넣어주었다.

 

post, get 함수 정의

클라이언트의 요청을 처리하기 위한 post, get함수를 movies/views.py에 정의해 주었다. ( 클라이언트 요청을 처리하기 위한 로직을 실행시키면  view에서 로직을 처리함.)

# views.py
class PizzaView(View):
    def post(self, request):
        data = json.loads(request.body)
        Pizza.objects.create(
            dough = data['dough'],
            size = data['size'],
        )
        return JsonResponse({'message':'created'}, status=201)
    def get(self,request):
        pizzas = Pizza.objects.all()
        results = []    
        for pizza in pizzas :
        	# related_name을 바꿔서 적용하면 실행이 되지 않는다
            topping = pizza.a.all()
            topping_list=[]
            for i in topping :
                topping_info = {
                    "opsion1": i.topping.opsion1,
                    "opsion2": i.topping.opsion2,
                }
            topping_list.append(topping_info)
        results.append(
          {
            "dough" : pizza.dough,
            "size" : pizza.size,
            "opsion" :topping_list,
           } 
        )
        return JsonResponse({'resutls':results}, status=200)   


class ToppingView(View):
    def post(self, request):
        data = json.loads(request.body)
        Topping.objects.create(
            opsion1 = data['opsion1'],
            opsion2 = data['opsion2'],
        )
        return JsonResponse({'message':'created'}, status=201)        
    def get(self, request):
        toppings = Topping.objects.all()
        results=[]
        for topping in toppings :
            pizza = topping.b.all()
            pizza_list = []
            for i in pizza :
                pizza_info ={
                    "dough": i.pizza.dough,
                    "size" : i.pizza.size,
                }
                pizza_list.append(pizza_info)
            results.append({
                "opsion1" : topping.opsion1,
                "opsion2" : topping.opsion2,
                "pizza_info" : pizza_list,
            }
            )
        return JsonResponse({'resutls':results}, status=200)

 Http request 요청

그리고 가상 환경에서 서버를 실행시키고 http 요청을 했을 때,

http -v get 127.0.0.1:8000/pizza/dough
http -v get 127.0.0.1:8000/pizza/topping

post/get request 문제없이 실행되었다. (post 내용 생략)

(pets) yujeong@xo-MacBook-Air pets % http -v get 127.0.0.1:8000/pizza/dough
GET /pizza/dough HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: 127.0.0.1:8000
User-Agent: HTTPie/3.2.1



HTTP/1.1 200 OK
Content-Length: 782
Content-Type: application/json
Cross-Origin-Opener-Policy: same-origin
Date: Wed, 06 Jul 2022 13:33:36 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.8.13
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "resutls": [
        {
            "dough": "ssin",
            "opsion": [
                {
                    "opsion1": "pineapple",
                    "opsion2": "shrimp"
                }
            ],
            "size": "small"
        },
        {
            "dough": "classic",
            "opsion": [
                {
                    "opsion1": "pineapple",
                    "opsion2": "shrimp"
                }
            ],
            "size": "medium"
        },

 

 


전문 참조 - mdn

'study > Django' 카테고리의 다른 글

Django - 회원가입 구현  (0) 2022.07.10
Django - QuerySet 다루기 (초보)  (0) 2022.07.09
westarbucks 만들기 - models.py  (0) 2022.07.05
Django tutorial 따라하기 4  (0) 2022.06.30
Django tutorial 따라하기 3  (0) 2022.06.29
댓글