Store dynamic choice field form from api call to be able to pass the verification in post request
I'm working on an app that can display the events coming from a google calendar.
To be able to do this, the user need to fill a form with the start date, end date, timezone and select a calendar.
I'm new to Django and it's ok to make a form with date, text, checkbox but regarding the choice field, it fail because the values are not present in the choice list.
Select a valid choice. johndoe@gmail.com is not one of the available choices.
This is normal because the values will change according to the user.
For that I'm calling the google calendar api before showing the page at GET request.
I tried to add it to the form but of course, it doesn't stay while the post method is called.
Is there a way to store the value without using the session or database?
How do you manage dynamic choice field that isn't coming from database?
Here is my code:
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 page
{% 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 %}