Я пытаюсь создать адаптивную турнирную скобку с помощью python / django и использую запросы $ .post для обновления турнирной информации - которую я передаю шаблону «скобок» в виде словаря, рендеринга, а затем обновления на $. отправка переданной переменной в другое представление, которое обновляется, сохраняется на сервере, а затем перенаправляется в представление «скобок».
Я только начинаю добиваться определенного прогресса, но у меня возникают проблемы с переформатированием объекта скобок.
Немного больше деталей
Скобка инициализируется в python (в моем views.py) в представлении скобки, но я вызываю в представлении турнир класс, который я получил от здесь .
класс Турнира берет список игроков и затем генерирует словарь, соответствующий играм, с помощью метода t.generate_bracket ().
Я как бы реструктурирую это, а затем передаю в скобки для отображения - я отображаю реструктурированный массив в своем шаблоне, но также передаю нереструктурированный
I есть маленькие переключатели, которые связаны с представлением $ .post 'update_bracket'. В JS $ .post я отправляю массив в представление, где я буду вызывать метод t.play_game () для обновления скобки. Затем - вместо ответа JSON или HTTP и последующего повторного заполнения клиентской части скобок (что я недостаточно хорош во внешнем интерфейсе), я сохраняю обновленную скобку в JSONField на модели сотрудника (расширяет зарегистрированную запись). в user) и HTTPResponseRedirect к начальному представлению «скобки», где у меня есть проверка, чтобы увидеть, есть ли у сохраненного в них скобка сотрудника, а затем использовать это значение, сохраненное в JSONField, как новую скобку, которая будет отображаться - вместо генерации с нуля с помощью t.generate_bracket ()
Вот мое представление скобок, мое представление обновлений, скобки. html с json $ .post () для update_bracket и некоторыми из турниров и других классов. Я использую
Код
Исходный вид скобки
@login_required#(login_url='/accounts/login/')
def bracket(request):
'''
:param request:
:return:
'''
emp = Employee.objects.get(user = request.user)
emp_bracket = emp.guess
players = [p.id for p in Pet.objects.all()]
t = Tournament(players)
if not emp_bracket:
t.generate_bracket('single', 0)
else:
t.games = emp_bracket
tournament_games = t.games
nested_tournament_games = {}
nested_tournament_games['rounds']={}
for g_id,g in tournament_games.items():
#....I do restructuring of the tournament_games dict
context = {'arr':tournament_games, 'nested':nested_tournament_games['rounds']}#{'latest_question_list': latest_question_list}
return render(request, 'madness/bracket.html', context)
.пост в шаблоне скобки
$('input[type=radio][name=bStatus]').change(function() {
alert(this.value);
$.post('{% url "update_bracket" %}',
{ bracketData: JSON.stringify("{{arr}}") },
function(data, status, xhr) {
console.log(JSON.stringify(data));
var nested = JSON.stringify(data);
}).done(function() { })
.fail(function(jqxhr, settings, ex) { alert('failed, ' + ex); });
});
update_bracket view
@csrf_exempt
def update_bracket(request):
bracketData = request.POST['bracketData']
print(json.loads(bracketData))
#I plan on using the play_game() method here, but first I have to just get the basics down
emp = Employee.objects.get(user = request.user)
emp.guess = bracketData
emp.save()
# return HttpResponse(json.loads(bracketData))
return HttpResponseRedirect(reverse('bracket'))
Турнирный класс, которым я пользуюсь
class Tournament:
def __init__(self, players):
self.players = players
self.player_count = len(players)
self.games = {}
...
def generate_bracket(self, bracket_class, randomize):
if bracket_class != "single":
print("Illegal bracket class")
quit()
self.n_size = int(math.ceil(math.log(self.player_count, 2)))
self.underflow = int(math.pow(2, self.n_size) - self.player_count)
if randomize:
random.shuffle(self.players)
for i in range(self.underflow):
self.players.append(None)
self.num_of_rounds = int(math.log(len(self.players), 2))
self.games = generate_bracket_rec(self.players, self.num_of_rounds)
...
def generate_bracket_rec(players, num_of_rounds):
games_map = {}
next_players = []
assert len(players) > 0
if len(players) == 1:
return games_map
gm=1
for i in range(int(len(players) / 2)):
player1_id = i
player2_id = len(players) - 1 - i
if players[player2_id] is None:
next_players.append(players[player1_id])
else:
round=str(1+num_of_rounds-int(math.log(len(players), 2)))
game_id = "round_"+round + "_game_" + str(gm)#str(i + 1)
g = Game((players[player1_id], players[player2_id]), game_id)
g.round, g.game = round, gm
games_map[g.id] = g#{'players':g.players, 'winner':g.winner, 'loser':g.loser, 'done':g.done}
# next_players.append((g, "winner")) #the winner of that game
# next_players.append('winner of %s and %s' % (g.players))
next_players.append('winner of Round %s Game %s' % (g.round, g.game))
gm += 1
d = {}
d.update(games_map)
d.update(generate_bracket_rec(next_players, num_of_rounds).items())
return d
Ошибки в форматировании
Я пробовал разные способы работы с турнирным объектом JSON, так как сейчас он стоит, ошибка, с которой я сталкиваюсь в js в $ .post - Uncaught SyntaxError: неверный или неожиданный токен, поэтому код даже не достигает update_bracket view.
DevTools показывает
$.post('/update_bracket',
{ bracketData: JSON.stringify("{'round_1_game_1': round_1_game_1: 2 vs 3
Done: False, 'round_2_game_1': round_2_game_1: 1 vs winner of Round 1 Game 1
Done: False}") },
Кто-нибудь знает, как мне нужно иметь дело с этим объектом турнира в жизненном цикле
python (генерируется как dict) - -> шаблон (переданный в качестве контекста var) -> python (из .post этого переданного в template-var) -> сохранить в django JSONField -> полученный из JSONField (перезапуск цикла)
РЕДАКТИРОВАТЬ - JSON Ошибка декодирования
После следующих советов о том, что делать с передачей в шаблон, я получаю новую ошибку в update_bracket. Я могу отправить данные туда, но затем, когда я пытаюсь загрузить (), я получаю ошибку JSONDecode. Вы знаете, как я могу справиться с этим?
request.POST['bracketData']
'{"round_1_game_1": {"players": [2, 3], "winner": null, "loser": null, "done": false}, "round_2_game_1": {"players": [1, "winner of Round 1 Game 1"], "winner": null, "loser": null, "done": false}}'
json.loads(request.POST['bracketData'])
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.2.1\helpers\pydev\_pydevd_bundle\pydevd_exec2.py", line 3, in Exec
exec(exp, global_vars, local_vars)
File "<input>", line 1, in <module>
File "C:\Users\aiden\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Users\aiden\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\aiden\AppData\Local\Programs\Python\Python37-32\lib\json\decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)