Как мне написать этот код более Pythoni c способ - PullRequest
0 голосов
/ 25 марта 2020

Я пишу представления Django, чтобы проверить, указан верный идентификатор альбома или нет. Но это выглядит громоздко и трудно читать. Я хочу сделать его более читабельным и коротким. Я не могу напрямую проверить data['id']. Это даст ошибку, если его пусто.

def post(self, request):
    if len(request.body) > 0:
        data = json.loads(request.body.decode('utf-8'))
    else:
        return Response({'message': 'Album id is required'})

    if 'id' not in data:
        return Response({'message': 'Valid Album id is required'})

    try:
        id = int(data['id'])
        if id < 1:
            return Response({'message': 'Valid album id is required'})
        album = Album.objects.get(pk=id)
    except:
        return Response({'message': 'Valid album id is required'})

Ответы [ 2 ]

1 голос
/ 25 марта 2020

При попытке повысить удобочитаемость следует помнить две большие вещи: не преждевременно оптимизировать и использовать функции для инкапсуляции логики c (особенно если эта логика c возможно, придется использовать повторно в будущем).

Итак, простой пример:

def post(self, request):
    if request.body:
        data = json.loads(request.body.decode('utf-8'))
    else:
        return Response({'message': 'Album id is required'})

    if _validate_data(data):
        id_ = int(data['id'])
        album = Album.objects.get(pk=id_)
        # probably want to return a Response as well...
    else:
        return Response({'message': 'Valid Album id is required'})


def _validate_data(data):
    if 'id' not in data:
        return False
    try:
        id_ = int(data['id'])
    except ValueError:
        return False
    return id_ >= 1

Есть разные подходы, которые вы можете использовать. Например, вместо _validate_data у вас может быть _extract_id, который возвращает None, когда data недействителен, в противном случае - id_, который вы затем проверите, так что-то вроде:

id_ = _extract_id(data)
if id_ is None:
    return Response({'message': 'Valid Album id is required'})
else:
    # do the rest of the stuff

Вы должны решить, что имеет больше смысла, учитывая остальную часть вашего кода и любые стандарты, которым вы следуете.

В общем, мне это не кажется постом, потому что кажется, что вы просто извлекая данные, альбом по идентификатору, POST обычно используется для создания нового ресурса.

1 голос
/ 25 марта 2020

Похоже, вся проблема в том, что делать, если id является недопустимой записью в data.

Глядя на ваш код, особенно на приведенную ниже часть, кажется, что id значение меньше 1 недопустимо.

 if id < 1:
    return Response({'message': 'Valid album id is required'})

Кроме того, try...except означает, что, если id не является частью data, то это также недопустимо.

Это означает, что ваш код можно упростить, используя значения по умолчанию, например:

def post(self, request):
    if len(request.body) > 0:
        data = json.loads(request.body.decode('utf-8'))
    else:
        return Response({'message': 'Album id is required'})

    id = int(data.get('id', 0))
    if id < 1:
        return Response({'message': 'Valid album id is required'})
    album = Album.objects.get(pk=id)
    # f-strings below are a python 3
    return Response({'message': f'The album you have requested is {album}'})

Важная часть приведенного выше фрагмента: data.get('id', 0), которая возвращает data['id'], если id является допустимым полем, и 0, если id не найден внутри data

Не имеет отношения, потому что оба являются допустимыми способами проверки request.body, но более Pythoni c способ сделать это, как @ juanpa.arrivillaga предложил а именно: if request.body:

Чтобы еще больше упростить его, я бы уменьшил некоторые дубликаты, выполнив это следующим образом:

def post(self, request):
    if request.body:
        data = json.loads(request.body.decode('utf-8'))

        id = int(data.get('id', 0))
        if id < 1:
            return Response({'message': 'Valid album id is required'})
        album = Album.objects.get(pk=id)
        # f-strings below are a python 3
        return Response({'message': f'The album you have requested is {album}'})

    return Response({'message': 'Album id is required'})
...