[DRF] user model 데이터를 랜덤으로 전송하기, 서버에서 랜덤으로 데이터 보내주기

[ 문제 상황]

 

DRF로 안드로이드와 서버를 연동하는 앱 프로그램을 개발 중이였다.

안드로이드에서 현재 사용자에게 다른 사용자 10명을 랜덤으로 추천해주기 위한 코드가 필요했다.

현재 사용자는 자신이 모르는 사용자를 추천 받아야 하므로 팔로우 중인 사용자를 제외한 리스트가 필요했다.

하지만 안드로이드에서 랜덤으로 사용자를 추출하기 위해서는 모든 사용자 리스트를 서버로 부터 받아와야 했기 때문에

이는 매우 비효율적이라고 생각하고 다른 방법을 찾아보았다.

 

[문제 해결]

 

가장 좋은 방법은 서버에서 랜덤으로 사용자들을 보내주는 것이다.

랜덤으로 사용자를 전송해주는 API View를 따로 제작해서 사용자에게 요청이 오면  서버에서 자체적으로 

랜덤 사용자 리스트를 보내주는 방식을 사용하였다.

 

<step 1>  우선 랜덤 리스트를 전송해줄 randomUserView 를 제작하였다.

class randomUserView(APIView):
   
    def post(self,request):

현재 사용자의 username이 post로 들어오면  팔로우 하지 않은 랜덤 사용자를 보내주는 코드를 작성할 것이다.

urlpatterns = [
    # url 리스트 
    path('randomuser/',randomUserView.as_view()),
]

사용자가 View에 접근할 수 있도록 url도 설정해준다.

 

<step 2>  전체 리스트 집합에서 자신과 자신이 팔로우하는 리스트를 빼준다.

 

        Profile_list = Profile.objects.all() #전체 리스트 집합
        Profile_list = [Profile_list[i] for i in range(0,len(Profile_list)) ] #쿼리셋 to 리스트
   
        username = Profile.objects.get(username=request.data['username']) #자신
        put_list = myfollowingProfileView.put_list_fg(self,username) # type: ignore #내팔로잉 리스트
        excludeList = set([put_list[i].toUser for i in range(0,len(put_list)) ] ) #쿼리셋 to set
        excludeList.add(username)

        #전체 리스트에서 내 팔로잉 리스트 , 내 아이디를 제외 시킴
        profileList = [i for i in Profile_list if i not in excludeList]

 

랜덤으로 데이터를 추출하기 위해서는 우선 내가 팔로우 하지 않은, 나 자신을 제외한 리스트를 만들어 준다.

쿼리셋을 리스트로 변환해주는 코드는 파이썬의 LIst Comprehension을 사용했다.

 

자세한 내용은 Python - List Comprehension (w3schools.com)

 

Python - List Comprehension

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

코드를 간결하게 작성할 수 있도록 도와주지만 복잡한 코드라면 오히려 실수할 수도 있으니 직접 풀어서 쓰는 것이 좋다.

 

<step 3 >  profileList 리스트에서 랜덤으로 10개의 데이터를 추출하기만 하면 된다.

import random # 랜덤 함수를 사용하기 위한 import

만약 리스트가 10명 이하라면 모든 유저를 추천해주고, 10명 이상이라면 총 10명의 데이터를 추출 해준다.

 

 
        #최대 10명, 최소 n명의 유저 수 추출
        rand_int =len(profileList) if len(profileList)<=10 else 10
        rand_list = random.sample(profileList,rand_int)
       
        randList = [MiniProfileSeralizer(put).data for put in rand_list ] #하나씩 넣어서 리스트 제작

이제 최종적으로 randList를 전송해주면 된다.

    return Response(randList, status=status.HTTP_200_OK)

 

 

[리뷰]

 

쿼리셋을 리스트로 변환할 때 LIst Comprehension을 사용해서 리스트를 하나씩 확인하는 방법을 사용했다.

아마도 바로 쿼리셋을 리스트로 변환해주는 함수가 있을 것 같은데 방법을 찾아봐야겠다.