*JSON 데이터를 전송할 것이며 다음과 같다.
{
"id" : 1,
"follow": 2
}
"id" 필드는 사용자의 id이다.
"follow" 필드는 사용자가 follow할 대상자의 id이다.
마찬가지로 *JSON 데이터를 전송할 것이며 다음과 같다.
{
"id" : 1,
"unfollow" : 2
}
"id" 필드는 사용자의 id이다.
"follow" 필드는 사용자가 unfollow할 대상자의 id이다.
위의 내용을 코드로 구성해야 한다.
'앞과 비슷하니 스스로 생각하여 구현해본 후 제시된 예제와 비교해보자'라고 적혀 있다.
구현해본다.
@app.route("/follow", methods=['POST']
def follow():
req_follow = request.json
req_follow_id = req_follow['id']
req_followed_id = req_follow['follow']
return jsonify(req_follow)
모르겠다. 그냥 제시된 예제를 볼 거임.
@app.route('/flow', methods=['POST']
def follow():
payload = request.json
user_id = int(payload['id'])
user_id_to_follow = int(payload['follow']
if user_id not in app.users or user_id_to_follow not in app.users:
return 'undefined user', 400
user = app.users[user_id]
user.setdefault('follow', set()).add(user_id_to_follow)
return jsonify(user)
전의 포스트에서 계속 이어지기 때문에
이전에 쓰던 변수를 기억하는 것이 매우 개떡같다.
일단 내 코드가 망한 이유?
망하면 안 되니까 알아 가야 함.
Python 내장 자료구조인 dict형을 사용하다보면
어떤 key에 대한 value가 없는 경우에 대한 처리를 해야 하는 경우가 발생한다.
key만 남고 value가 없는 dict를 set이라 하며,
dict와 마찬가지로 각 key값은 유일해야 한다.
dict.setdefault(첫 번째 인자, 두 번째 인자)
에서
key값이 존재한다면 key값을 반환하고 없다면 기본값을 반환한다.
user.setdefault('follow', set()).add(user_id_to_follow)
에서
첫 번재 인자는 'follow'이고
두 번째 인자는 set()이다.
'follow'가 이미 있다면 'follow'반환하고 .add(user_id_to_follow)
까지 실행하여
'follow'에 user_id_to_follow를 key값으로 넣는다.
'follow'가 없다면 set():empy set과 연결하여 추가한다.
해당 사용자가 follow하는 다른 사용자들의 id를 저장하는 자료구조로 set을 사용하는 이유는?
이미 follow하고 있는 id를 또 follow하겠다는 요청이 들어왔을 때, 동일한 id가 여러번 저장되는 일이 없기 때문이다.
Python 자료구조의 dict와 set에서 각 key값은 유일하다.
아무튼 이 코드를 적당히 또 섞어줘야 함.
어디에?
app.py에
그러고나서 다시 회원가입 요청부터( /sign-up ) 다시 해주고
follow 요청을 해주겠다.
$ http -v POST http://localhost:5000/follow id=1 follow=2
이렇게 터미널에 입력해주면
OK 응답을 볼 수가 있다.
@app.route('/unfollow', methods=['POST'])
def unfollow():
payload = request.json
user_id = int(payload['id'])
user_id_to_follow = int(payloadp['unfollow'])
if user_id not in app.users or user_id_to_follow not in app.users;
return 'undefined user', 400
user = app.user[user_id]
user.setdefault('follow', set()).discard(user_id_to_follow)
return jsonify(user)
달라진 점은 .add
대신 .discard
를 쓴다는 것이다.
추가 대신 삭제를 수행해야 하기 때문이다.
.remove
대신.discard
를 쓰는 이유?
.remove
는 없는 값 지우려 하면 난리를 침. 오류가 남.
그런데.discard
는 지우려 하는 값이 존재하면 삭제하고 없으면 무시함.
상황에 맞게 더 나은 걸 쓰면 될 듯하다.
코드를 짰으니 이것도 돌려봤다.
$ http -v POST http://localhost:5000/unfollow id=1 follow=2
오타를 몇 번이나 수정한 끝에 간신히 되는 걸 확인했다.
만약 이런 오류가 뜬다면
원인은 Python의 json모듈이 set 자료구조를 JSON으로 변경하지 못하기 때문이므로 코드를 좀 작성해줘야 한다.
from flask.json import JSONEncoder
class CustomJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return JSONEncoder.default(self, obj)
app.json_encoder = CustomJSONEncoder
JSON 엔코더를 커스텀해서 기존의 JSON 엔코더에 덮어씌우는 과정이다.
set을 list로 변경해줌으로써 문제없이 JSON으로 변경 가능하도록 해준다.