I'm at my wit's end. I've scoured stackoverflow for similar issues to no avail and eventually gave up on resolving the issue.
I've built a pet project in django that uses an input form to search a SQLite database to convert lunar dates into gregorian dates and vice versa. Everything has worked properly so far, but now I'm trying to build chained dependencies where the day field dropdown only lists the appropriate number of days for the selected month. I'm using the django-smart-selects module to try to accomplish this.
However, the Month dropdown now lists every single date (the table's primary key) from my table in the form of:
The Month dropdown should only list months 1 - 12. The Day dropdown doesn't populate at all. I've tried removing the primary key field, but then I get the following error message:
django.db.utils.OperationalError: no such column: Converter.id
where Converter is the name of the table in my model.
Can someone please shed some light on this?
models.py
from django.db import models
from smart_selects.db_fields import ChainedForeignKey
MONTH_RANGE_CHOICES = [(i, i) for i in range(1, 13)]
DAY_RANGE_CHOICES = [(i, i) for i in range(1, 32)]
YEAR_RANGE_CHOICES = [(i, i) for i in range(1901, 2101)]
class Month(models.Model):
name = models.IntegerField('Lunar Month', db_column='Lunar Month', choices=MONTH_RANGE_CHOICES, default='Month')
gregorian_date = models.TextField('Gregorian Date', db_column='Gregorian Date', unique=True, primary_key=True)
class Meta:
managed = False
db_table = 'Converter'
class Day(models.Model):
month = models.ForeignKey(Month, on_delete=models.CASCADE)
name = models.IntegerField(choices=DAY_RANGE_CHOICES)
class Meta:
managed = False
db_table = 'Converter'
class DateConverter(models.Model):
gregorian_date = models.TextField('Gregorian Date', db_column='Gregorian Date', unique=True, primary_key=True)
month = models.ForeignKey(Month, on_delete=models.CASCADE)
day = ChainedForeignKey(
Day,
chained_field='month',
chained_model_field='month',
show_all=False,
auto_choose=True,
sort=False
)
year = models.IntegerField('Lunar Year', db_column='Year', choices=YEAR_RANGE_CHOICES, default='Year')
class Meta:
managed = False
db_table = 'Converter'
views.py
from django.shortcuts import render, get_object_or_404, render_to_response, redirect
from django.urls import reverse
from converter.forms import LunarDateForm, GregorianDateForm
from converter.models import DateConverter
def lunar_conversion(request):
template_name = 'converter/lunar.html'
form = LunarDateForm(request.GET or None)
date = None
if form.is_valid():
date = DateConverter.objects.filter(month=form.cleaned_data.get('month'),
day=form.cleaned_data.get('day'),
year=form.cleaned_data.get('year'))\
.values_list('gregorian_date', 'day_of_week')
date = date[0]
context = {
'form': form,
'date': date,
}
return render(request, template_name, context)
forms.py
from django import forms
from converter.models import DateConverter
class LunarDateForm(forms.ModelForm):
class Meta:
model = DateConverter
fields = [
'month',
'day',
'year'
]
urls.py
from django.urls import path, include, re_path
from . import views
urlpatterns = [path('luna', views.lunar_conversion, name='lunar conversion'),
path('greg', views.gregorian_conversion, name='gregorian conversion'),
re_path(r'^chaining/', include('smart_selects.urls')),
]
html template
{% load static %}
{% block content %}
<div class="offset-1 col-md-10 text-center" id="form">
<div class="alert alert-secondary">
<form method='GET' action=''>
{% csrf_token %}
{{ form.media.js }}
{{ form.as_p }}
<button type="submit" class="btn btn-primary btn-sm">Submit</button>
</div>
<br>
<div class="rounded p-3 mb-2 bg-light text-dark">
<p><b>Gregorian Date:</b> {{ date.0 }}</p>
<br>
<p><b>Day of the Week:</b> {{ date.1 }}</p>
<br>
</div>
</div>
{% include "converter/includes/htmlsnippet.html" %}
{% endblock %}