Реализация пользовательского класса Django rest api

#django #rest #django-class-based-views

#django #rest #представления на основе классов django

Вопрос:

Я создал класс для извлечения данных о конкретном пищевом продукте из farsecret API. В классе я создал 3 функции для:

* получение авторизации

* получаем идентификатор элемента, который мы ищем

* загрузка данных элемента

 class IngredientImport(APIView):

def get_authorization_token(self):
    request_token_url = "https://oauth.fatsecret.com/connect/token"
    consumer_key = os.environ.get('NTS_Client_ID')
    consumer_secret = os.environ.get('NTS_Client_Secret')
    data = {'grant_type':'client_credentials', "scope":"basic"}

    access_token_response = requests.post(
        request_token_url, 
        data=data, 
        verify=False, 
        allow_redirects=False, 
        auth=(consumer_key, consumer_secret)
    )
    return access_token_response.json()["access_token"]


def get_list_by_name(self, name, access_token):
    api_url = "https://platform.fatsecret.com/rest/server.api"
    params={
        "method":"foods.search", 
        "search_expression":name, 
        "page_number":1, 
        "max_results":1, 
        "format":"json"
    }
    header = {"Authorization":access_token}
    api_call_headers = {"Authorization": "Bearer "   access_token}

    response = requests.get(
        api_url,
        params=params,
        headers=api_call_headers
    )
    items = response.json()["foods"]
    try:
        return response.json()["foods"]["food"]["food_id"]
    except KeyError:
        return None


def import_item(self, item_id, api_token):
    if item_id == None:
        return None

    api_url = "https://platform.fatsecret.com/rest/server.api"
    params={"method":"food.get", "food_id":item_id, "format":"json"}
    api_call_headers = {"Authorization": "Bearer "   access_token}  

    response = requests.get(
        api_url,
        params=params,
        headers=api_call_headers
    )
    item = response.json()["food"]["servings"]["serving"]
    item_name = response.json()["food"]["food_name"]
    if type(item) == list:
        item = item[0]
    try:
        portion_size = float(item["metric_serving_amount"])
        carbs = round(float(item["carbohydrate"]) / portion_size * 100, 2)
        fats = round(float(item["fat"]) / portion_size * 100, 2)
        proteins = round(float(item["protein"]) / portion_size * 100, 2)            
    except KeyError:
        return None
  

Как я могу реализовать этот класс в своем приложении, чтобы избежать создания 3 разных путей в urls.py для каждой функции. Возможно ли это или я должен разбить его на представления, основанные на функциях?

Ответ №1:

 class IngredientImport(APIView):

    def get_authorization_token(self):
       ...
 
    def get_list_by_name(self, name, access_token):
       ...

    def import_item(self, item_id, api_token):
       ...

    def get(self, request):
       # get name from query param
       name = self.request.GET.get('name')

       token = self.get_authorization_token()
       food_list = self.get_list_by_name(name, token)

       for food_id in food_list:
           self.import_item(food_id, token)

       return Response({'imported_foods': food_list})
  

Затем, на вашем urls.py:

 urlpatterns = [
   path('import_foods', IngredientImport.as_view())
]