Ken,
Thank you for taking the time to check on this error. I changed some field names to verify there is no overlap and reran it twice. First time not setting a limit queryset when form.is_bound and getting no error. Second time through setting limit queryset on both the bound and unbound cases. Error only happens on the second case.
Below are the model, form and view as well as console output from both the good and error runs. Note debug logging in console output and view and form code.
==========================================================
models.py
class Ingredient(models.Model):
element = models.ForeignKey(Element, on_delete=models.CASCADE)
glaze = models.ForeignKey(Glaze, on_delete=models.CASCADE)
quantity = models.DecimalField(max_digits=6, decimal_places=3, null = True, blank = True) # % of element in glaze mixture
def __str__(self):
s = f'{self.glaze.name} : {self.element.name} | above the line'
return s
# only one element/glaze pairing for colorant or element
class Meta:
constraints = [
models.UniqueConstraint(fields = ['element_id', 'glaze_id'], name = 'duplicate_element_in_glaze')
]
=================================================================
forms.py
class AddGlazeIngredientForm(ModelForm):
def __init__(self, *args, **kwargs):
logging.debug('AddGlazeIngredientForm')
gid = kwargs.pop('gpk', None) # this is pk of glaze object
super().__init__(*args, **kwargs)
# if not self.is_bound:
# build queryset that contains no objects already in glaze recipe
g = Glaze.objects.get(id = gid) # current glaze object whose pk is passed through view kwargs
qsg = g.ingredients.all() # all elements in glaze
qse = Element.objects.all() # all allowable elements
qs = qse.difference(qsg).order_by('name') # queryset difference
self.fields['element'].queryset = qs
self.which = 'ingredient' # used in common template
# end block if not self.is_bound
logging.debug('leaving AddGlazeIngredientForm')
class Meta:
model = Ingredient
fields = ['element', 'quantity']
================================================================
views.py
class GlazeAddIngredient(SuccessMessageMixin, LoginRequiredMixin, generic.CreateView):
form_class = AddGlazeIngredientForm
template_name = 'glazes/add_to_glaze_form.html'
success_url = reverse_lazy('glazes:glazes list')
success_message = 'New ingredient added.'
def get_success_url(self):
return reverse_lazy('glazes:glaze detail', args=[self.kwargs['pk']]) # back to Glaze update form
def form_valid(self, form):
logging.debug('GlazeAddIngredient')
form.instance.glaze = Glaze.objects.get(id = self.kwargs['pk'])
return super(GlazeAddIngredient, self).form_valid(form)
def get_form_kwargs(self, **kwargs):
# Note there's a difference between the local variable kwargs used by
# this function and the instance variable self.kwargs
logging.debug('GlazeAddIngredient')
kwargs = super().get_form_kwargs()
kwargs['gpk'] = self.kwargs['pk']
return kwargs
================================================================
console log with the code block under
if not form.is_bound:
Django version 3.1.1, using settings 'glazeman.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[20/Oct/2020 11:00:13] "GET /glazeman/glaze/4 HTTP/1.1" 200 7882
[20/Oct/2020 11:00:14] "GET /static/glazes/icons/site.webmanifest HTTP/1.1" 304 0
DEBUG: 11:00:16 views get_form_kwargs 201 GlazeAddIngredient
DEBUG: 11:00:16 forms __init__ 28 AddGlazeIngredientForm
DEBUG: 11:00:16 forms __init__ 38 leaving AddGlazeIngredientForm
[20/Oct/2020 11:00:16] "GET /glazeman/glaze/4/add HTTP/1.1" 200 5523
DEBUG: 11:00:29 views get_form_kwargs 201 GlazeAddIngredient
DEBUG: 11:00:29 forms __init__ 28 AddGlazeIngredientForm
DEBUG: 11:00:29 forms __init__ 38 leaving AddGlazeIngredientForm
DEBUG: 11:00:29 views form_valid 194 GlazeAddIngredient
[20/Oct/2020 11:00:29] "POST /glazeman/glaze/4/add HTTP/1.1" 302 0
[20/Oct/2020 11:00:29] "GET /glazeman/glaze/4 HTTP/1.1" 200 8343
C:\Users\Ken\Python\Django\glazeman\glazes\forms.py changed, reloading.
INFO: 11:01:41 autoreload trigger_reload 236 C:\Users\Ken\Python\Django\glazeman\glazes\forms.py changed, reloading.
DEBUG: 11:01:41 proactor_events __init__ 623 Using proactor: IocpProactor
Watching for file changes with StatReloader
Performing system checks...
================================================================
console log without check on form.is_bound
Django version 3.1.1, using settings 'glazeman.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
DEBUG: 11:02:12 views get_form_kwargs 201 GlazeAddIngredient
DEBUG: 11:02:12 forms __init__ 28 AddGlazeIngredientForm
DEBUG: 11:02:13 forms __init__ 38 leaving AddGlazeIngredientForm
[20/Oct/2020 11:02:13] "GET /glazeman/glaze/4/add HTTP/1.1" 200 5475
DEBUG: 11:02:18 views get_form_kwargs 201 GlazeAddIngredient
DEBUG: 11:02:18 forms __init__ 28 AddGlazeIngredientForm
DEBUG: 11:02:18 forms __init__ 38 leaving AddGlazeIngredientForm
Internal Server Error: /glazeman/glaze/4/add
Traceback (most recent call last):
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\edit.py", line 141, in post
if form.is_valid():
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 177, in is_valid
return self.is_bound and not self.errors
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 172, in errors
self.full_clean()
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 374, in full_clean
self._clean_fields()
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 392, in _clean_fields
value = field.clean(value)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\fields.py", line 149, in clean
value = self.to_python(value)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\models.py", line 1274, in to_python
value = self.queryset.get(**{key: value})
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\db\models\query.py", line 433, in get
raise self.model.MultipleObjectsReturned(
glazes.models.Element.MultipleObjectsReturned: get() returned more than one Element -- it returned more than 20!
ERROR: 11:02:18 log log_response 224 Internal Server Error: /glazeman/glaze/4/add
Traceback (most recent call last):
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\views\generic\edit.py", line 141, in post
if form.is_valid():
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 177, in is_valid
return self.is_bound and not self.errors
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 172, in errors
self.full_clean()
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 374, in full_clean
self._clean_fields()
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\forms.py", line 392, in _clean_fields
value = field.clean(value)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\fields.py", line 149, in clean
value = self.to_python(value)
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\forms\models.py", line 1274, in to_python
value = self.queryset.get(**{key: value})
File "C:\Users\Ken\Python\Django\glazeman\venv\lib\site-packages\django\db\models\query.py", line 433, in get
raise self.model.MultipleObjectsReturned(
glazes.models.Element.MultipleObjectsReturned: get() returned more than one Element -- it returned more than 20!
[20/Oct/2020 11:02:18] "POST /glazeman/glaze/4/add HTTP/1.1" 500 114719