본문으로 바로가기

장고 CRUD 기능 구현(2) Read

category 장고/MTV 2019. 5. 7. 20:51

Read(읽기)

  • 대표적인 (소위 말하는) product-list, product-detail
    • product-list 는 모델의 쿼리셋에 접근한다.
    • product-detail 은 모델의 객체에 접근한다.

쿼리셋과 객체

간단하게 객체는 DB 에서 하나의 필드에만 로드, 쿼리셋은 조건에 부합하는 모든 필드를 로드

> product = Product.objects.get(pk=pk) # 객체 하나만
product.name 과 같은 필드의 속성에 접근 가능


> Product.objects.all() # 2개 이상의 객체를 불러옴
> Product.objects.filter(area='Seoul') # Seoul 에 해당하는 모든 객체를 불러옴
product.name 에 접근이 불가능함(여러 객체를 다 불러왔는데 이 중에서 어떤 객체.name 에 접근할지 모름)

Product Model

class Product(models.Model):
    description = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=9, decimal_places=2)
    quantity = models.IntegerField()

    def __str__(self):
        return self.description

> views.py 에서 핸들링

  • post-list 는 상품의 모든 페이지를 렌더링 함
  • post-detail 은 Product 모델의 1개의 필드(객체)에만 접근
def product_list(request):
    products = Product.objects.all().order_by('-pk')
    context = {
        'products': products,
    }
    return render(request, 'product/product-list.html', context)

**상품 디테일 페이지**

  • Product 모델에서 1개의 객체에만 접근하는 방법 3가지

  • 단순 접근은 get_object_or_404 가 편함

  • 접근한 객체에서 한단계 더 들어가는 접근 방법은 3번째가 편함

    • shop = Shop.objects.get(pk=pk)
    • product = Product.objects.get(pk=shop.pk)
def product_detail(request, pk):
     #1. 문서에서의 권장사항
    product = get_object_or_404(Product, pk=pk)

    #2. 두번째 권장사항
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        raise Http404

    #3. 기본 접근 방법
    product = Product.objects.get(pk=pk)

    context = {
        'product': product
    }
    return render(request, 'product/product-detail.html', context)

> 템플릿

  • product-list 페이지에서 {% for product in products %} 또는 product-detail 에서의{{ product }} 의 정의는 views 에서 정의한 context 를 렌더링하여 템플릿에 뿌려주기 때문이다.
def post_list(request): # 들어오는 request 는 render 에 다시 나가는 흐름을 가진다
    ...
    context = {
        'products': products, # 이 context 가 템플릿에서 사용할 수 있다
        }
    # 메서드의 파라미터로 들어온 request 는 쭉쭉 아래로 내려와서 렌더링할 때 다시 보내진다
    return render(request, '뿌려지는 템플릿', context)
# product-list.html 에서 디테일 페이지로 접근
{% for product in products %}
            <li><a href="{% url 'product:detail' product.pk %}">{{ product.description }}</a></li>
            <li>{{ product.price }}</li>
            <li>{{ product.quantity }}</li>
            <hr>
        {% endfor %}


# product-detail.html 에서 해당하는 pk 의 페이지를 보여줌
{% extends 'base.html' %}

{% block content %}

    <h2>디테일 페이지 [{{ product.pk }}]</h2>
    <ul>
        <li><div>{{ product.description }}</div></li>
        <li><div>{{ product.price }}</div></li>
        <li><div>{{ product.quantity }}</div></li>
    </ul>

    <br>
    <a href="{% url 'product:update' product.pk %}">수정하기</a>
    <br>
    <br>
    <a href="{% url 'product:delete' product.pk %}">삭제하기</a>
    <br>
    <br>
    <a href="{% url 'product:products' %}">홈으로 가기</a>

{% endblock %}

> 결론

CRUD 에서 Read 는 객체와 쿼리셋에 대한 이해만 명확하다면 구현하는데는 무리없다.

'장고 > MTV' 카테고리의 다른 글

장고 CRUD 기능 구현(4) Delete  (0) 2019.05.07
장고 CRUD 기능 구현(3) Update  (0) 2019.05.07
장고 CRUD 기능 구현(1) Create  (0) 2019.05.07
Login 기능 구현하기  (0) 2019.04.21
User 모델에서 Username 을 Email 로 재정의  (0) 2019.04.18