Храните динамическую форму поля выбора из вызова api, чтобы иметь возможность передать проверку в пост-запросе
Я работаю над приложением, которое может отображать события, поступающие из календаря google.
Чтобы иметь возможность сделать это, пользователю нужно заполнить форму с начальной датой, конечной датой, часовым поясом и выбрать календарь.
Я новичок в Django и это нормально сделать форму с датой, текстом, чекбоксом, но что касается поля выбора, это не удается, потому что значения не присутствуют в списке выбора.
Select a valid choice. johndoe@gmail.com is not one of the available choices.
Это нормально, потому что значения будут меняться в зависимости от пользователя.
Для этого я вызываю google calendar api перед тем, как показать страницу при GET запросе.
Я пытался добавить его в форму, но, конечно, он не остается, пока вызывается метод post.
Есть ли способ хранить значение без использования сессии или базы данных?
Как вы управляете динамическим полем выбора, которое не поступает из базы данных?
Вот мой код:
form.py
from django import forms
class events_filters(forms.Form):
start = forms.DateField(label='Start date')
end = forms.DateField(label='End date')
calendar = forms.ChoiceField(label='Select calendar')
timezone = forms.BooleanField(label="Show timezone")
view.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from allauth.socialaccount.models import SocialApp, SocialAccount
import csv
from django.http import HttpResponse
from .forms import events_filters
# Create your views here.
# Main page
@login_required(login_url='/accounts/google/login/')
def index(request):
if request.method == "GET":
creds = create_credentials(request)
calendars = getCalendars(creds) #function to get the calendars
form = events_filters()
form.fields["calendar"].choices = calendars #tried to add the calendars to the form, it work but of course doesn't stay for the post request
return render(request, "ts_index.html", context={"calendars":calendars, 'form': form})
if request.method == "POST":
form = events_filters(request.POST)
if form.is_valid(): # Failed here because the form doesn't know the values to be validated. I would like to be able to validate the data without passing by the client to be sure that the user use an email in the list. I would also like to avoid to call the calendar api again.
parameters = {
"start_date" : form["start"] + "T00:00:00.000Z",
"end_date" : form["end"] + "T00:00:00.000Z",
"calendar_id" : form["calendar"],
}
# Use the access token to authenticate with the Google Calendar API
creds = create_credentials(request)
events = getEvents(creds, parameters["start_date"], parameters["end_date"], parameters["calendar_id"])
return render(request, "ts_input_data.html", context={'events':events, "parameters": parameters})
else :
print("Data not valid")
Html страница
{% extends 'head.html' %}
{% load socialaccount %}
<!--Block content goes below-->
{% block content %}
<h1>Input data</h1>
<!-- Select the dates -->
<form method="POST" class="d-flex flex-column justify-content-center align-items-center" >
<!-- Key for CSRF -->
{% csrf_token %}
<!-- Select the agenda -->
<div class="mb-3 w-100">
<label for="calendar" class="form-label">Select calendar</label>
<select name="calendar" id="calendar_id" class="form-control">
{% for c in calendars %}
<option value=" {{ c.0 }} ">{{ c.1 }}</option>
{% endfor%}
</select>
</div>
<!-- Start date -->
<div class="mb-3 w-100">
<label for="start_id" class="form-label">Start date</label>
<input type="date" class="form-control" id="start_id" name="start">
</div>
<!-- End date -->
<div class="mb-3 w-100">
<label for="end" class="form-label">End date</label>
<input type="date" class="form-control" id="end_id" name="end">
</div>
<!-- End date -->
<div class="mb-3 w-100">
<label for="timezone" class="form-label">Show time-zone</label>
<input type="checkbox" class="form-check-input" id="timezone_id" name="timezone" checked>
</div>
<!-- Submit -->
<button type="submit" class="btn btn-primary w-100">Submit</button>
</form>
{% endblock %}