💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    14 피드 페이지 포스트 조회 로직 | ✅ 편저: 코담 운영자

    14강 - 피드 페이지 포스트 조회 로직

    조회 for 피드 페이지


    ✨ 이번 강의 목표

    • 피드 페이지에 보여줄 포스트 데이터를 조회한다
    • 로그인한 사용자의 포스트 + 팔로잉한 유저의 포스트 조회
    • QuerySet과 Q 객체를 활용한 조건 필터링 구현

    1. 사전 작업

    해당 강의에서는 다음과 같은 사전 설정이 선행되었습니다:

    • Post 모델: __str__ 메서드 추가 → 어드민 페이지나 셸에서 객체 구분 용이
    • Comment 모델: 동일하게 __str__ 메서드 정의 + PostAdmin에 inline 등록 → 게시물과 댓글을 함께 관리 가능
    • User 모델: followings 필드를 통해 팔로우 관계를 ManyToMany로 설정 → 어드민에서 다중 선택 가능
    • 테스트용 유저/포스트 생성 및 팔로잉 관계 사전 세팅

    위 작업은 관리자 페이지를 활용한 테스트 데이터 입력과 연계됩니다.

    • Post 모델에 __str__ 메서드 정의: 관리페이지 등에서 객체 식별 용이
    • Comment 모델도 동일하게 __str__ 메서드 작성
    • Comment 모델을 PostAdmin에 inline으로 등록 → 관리자가 댓글도 함께 관리 가능
    • User 모델의 followings 필드를 통해 유저 간 팔로우 관계 구현

    → 위 작업은 장고 admin에서 테스트 데이터를 생성하기 위해 선행됨


    2. 피드 포스트 조회 기준

    ✅ 출력 기준

    피드에는 다음 조건을 만족하는 포스트만 표시됩니다:

    • 내가 작성한 포스트 (Post.author == me)
    • 내가 팔로우하고 있는 유저가 작성한 포스트 (Post.author in me.followings)

    즉, "나 + 내가 팔로잉한 사람들"의 글만 필터링해야 함

    ✅ 피드에 출력할 포스트 조건

    • 내가 작성한 포스트
    • 내가 팔로우한 유저가 작성한 포스트

    → 즉, "나 + 내가 팔로잉한 사람들"의 포스트만 필터링해서 가져와야 함


    3. 뷰 로직 (인증 분기 포함)

    posts/views.py

    from django.shortcuts import render , get_object_or_404
    from django_instagram.users.models import User as user_model  # 사용자 모델 import
    from . import models 
    from .forms import CreatePostForm
    from django.db.models import Q
    
    def index(request):
        if request.method == 'GET': 
            if request.user.is_authenticated:
                """
                    models.Post.objects.filter(...):
    
                    1.models.Post: Post는 게시글 모델로, 데이터베이스의 게시글 테이블과 매핑된 Django 모델입니다.
                        1).objects: 모델에 대해 데이터베이스 쿼리를 실행할 수 있는 관리 매니저입니다.
                        2).filter(): 특정 조건에 해당하는 레코드만 필터링하여 반환하는 ORM 메서드입니다.
    
                    2.Q 객체:
                        **Q**는 Django의 ORM에서 OR 조건을 처리하거나 복잡한 조건을 생성할 때 사용하는 객체입니다.
    
                    3.결과:
                        posts 변수에는 다음 두 조건을 만족하는 게시글들이 저장됩니다
                        1)팔로우 중인 사용자가 작성한 게시글
                        2)현재 사용자가 작성한 게시글
    
                    4.author__in :author__in은 변수로 저장되는 것이 아니라 author__in은 쿼리를 생성하기 위한 조건 설정에만 사용됩니다.
                        1)author 필드:
                            Post 모델의 author 필드입니다. 이 필드는 ForeignKey로 연결되어 있으며, 게시글의 작성자를 나타냅니다
                        2)_in 룩업:
                            Django의 쿼리 필터링 옵션 중 하나로, 특정 값들의 리스트, 쿼리셋, 또는 iterable 객체 안에 포함된 레코드를 조회합니다.
                            예) models.Post.objects.filter(author__in=[user1, user2]) 여기서 author가 user1 또는 user2인 게시글을 필터링합니다.
                """           
                # 사용자 정보 가져오기
                user = get_object_or_404(user_model, pk=request.user.id)
                following=user.following.all()
                posts=models.Post.objects.filter(
                        Q(author__in=following) | Q(author=user)
                )
                return render(request, 'posts/main.html')
    

    ✅ 설명

    • 로그인되지 않은 사용자는 users/main.html로 리디렉션
    • Q() 객체로 복수 조건(OR) 필터링 구현
    • author__in=following_users는 내가 팔로우한 유저들의 포스트
    • author=me는 내가 직접 작성한 포스트
    • .order_by('-created'): 최신 순 정렬

    4. QuerySet 필터링 설명

    🔍 Q 객체란?

    Q() 객체는 장고 ORM에서 복잡한 조건식을 만들 때 사용되는 도구입니다.

    • | (OR), & (AND)와 결합 가능
    • 필터 조건을 유연하게 조합할 수 있음
    • 여러 조건을 조합할 수 있는 도구
    • & (AND), | (OR) 등을 사용해 복잡한 필터링 작성 가능
    Q(author=me) | Q(author__in=followings)
    

    → 위와 같이 두 조건을 "또는"으로 연결 가능

    🔍 __in 키워드란?

    field__in=[리스트] 구조로 사용하며, 해당 필드가 리스트 안 값 중 하나라도 포함되면 필터링 조건 통과합니다.

    • 여러 개 값 중 하나라도 포함되면 필터링 통과

    예: author__in=[유저1, 유저2, 유저3]

    → 해당 유저들이 작성한 포스트를 모두 가져옴


    5. Django Admin에서 User 모델 커스터마이징

    🔧 users/admin.py

    from allauth.account.decorators import secure_admin_login
    from django.conf import settings
    from django.contrib import admin
    from django.contrib.auth import admin as auth_admin
    from django.utils.translation import gettext_lazy as _
    
    from .forms import UserAdminChangeForm, UserAdminCreationForm
    from .models import User
    
    if settings.DJANGO_ADMIN_FORCE_ALLAUTH:
        admin.autodiscover()
        admin.site.login = secure_admin_login(admin.site.login)
    
    @admin.register(User)
    class UserAdmin(auth_admin.UserAdmin):
        form = UserAdminChangeForm
        add_form = UserAdminCreationForm
        fieldsets = (
            (None, {"fields": ("username", "password")}),
            (_("Personal info"), {"fields": ("name", "email")}),
            (_("팔로워 && 팔로잉"), {"fields": ("followers", "following")}),
            (_("Permissions"), {
                "fields": (
                    "is_active", "is_staff", "is_superuser", "groups", "user_permissions"
                ),
            }),
            (_("Important dates"), {"fields": ("last_login", "date_joined")}),
        )
        list_display = ["username", "name", "is_superuser"]
        search_fields = ["name"]
    

    ✅ 설명

    • Django 기본 UserAdmin 클래스를 확장하여 사용자 정의 모델에 맞게 관리 화면 구성
    • fieldsets을 활용해 필드 그룹을 세분화 (프로필, 권한, 날짜 등)
    • list_display, search_fields로 관리 효율 향상
    • secure_admin_login()으로 로그인 경로를 django-allauth와 연동

    ✅ 정리

    • request.user.is_authenticated: 로그인 여부 판단 → 인증 안 된 유저는 users/main.html로 리디렉션
    • get_object_or_404(user_model, pk=request.user.id): 로그인된 유저 객체 가져오기 (존재하지 않으면 404 반환)
    • me.followings.all(): 현재 유저가 팔로잉하고 있는 유저 리스트
    • Post.objects.filter(Q(...)): Q 객체를 사용한 다중 조건 필터링
    • .order_by('-created'): 최신 순으로 정렬

    💡 예시 상황 복습

    • 철수, 영희, 민수가 있고, 내가 철수와 영희를 팔로우한 상태라면: → 철수와 영희의 포스트 + 내 포스트만 피드에 나타나야 함

    • 피드 페이지에서는 내가 쓴 글과 내가 팔로잉한 유저들의 글만 보인다

    • 이를 위해 Q() 객체와 __in 필터를 함께 사용

    • 로그인 여부에 따라 분기 처리 필수

    • 추출한 포스트는 템플릿으로 넘겨서 출력

    👉 다음 강의에서는 추출한 포스트를 시리얼라이저(Serializer)를 통해 JSON 구조로 직렬화합니다.

    TOP
    preload preload