Ah, thank you for the link; it put me on the right track, I think, with custom validators.
As an example of why I need to customize the item fetching: I have an item that has an item_number of '515874'. That number is how the users interact with the item. However, the primary key for Item '515874' is 41293, which the users don't know anything about. That way they can maintain their own internal numbering/sku system, and we don't have to worry about data integrity when they do what they need to with them. So since Django is looking for a primary key of 515874 and not finding it, it raises a ValidationError and gives up before I can get to it to tell it what the pk really is; defining my own field solved that. But Django is still doing something automagically, because I changed the value that it passed through my validators, returned that value, and then Django starts cleaning it... but it's trying to clean the original '515874', not 41293, which is the value my validator returned. (I might need to start a new post simply because the topic has changed so much.) Thanks so much! class ItemNumField(forms.CharField): def validate(self, value): # item = Item.objects.get(item_number=value) # value = item.id # return value return Item.objects.get(item_number=value) class AddItem(forms.ModelForm): item = ItemNumField() class Meta: model = ItemsTestCollection # fields = ['item', 'qty', 'case'] fields = ['item', 'qty', 'case'] class ItemsTestCollection(models.Model): """An item to be tested in Box Opt.""" item = models.ForeignKey('item.Item', on_delete=models.CASCADE) qty = models.IntegerField() case = models.ForeignKey('EvaluateTestCase', on_delete=models.CASCADE) box = models.ForeignKey('BoxResults', on_delete=models.CASCADE, null=True) ValueError at /utils/box-optimization/add-items/118 Cannot assign "'515874'": "ItemsTestCollection.item" must be a "Item" instance. Request Method: POST Request URL: http://localhost:8000/utils/box-optimization/add-items/118 Django Version: 2.0.5 Exception Type: ValueError Exception Value: Cannot assign "'515874'": "ItemsTestCollection.item" must be a "Item" instance. Exception Location: C:\miniconda3\envs\django\lib\site-packages\django\db\models\fields\related_descriptors.py in __set__, line 197 Python Executable: C:\miniconda3\envs\django\python.exe Python Version: 3.6.5 Python Path: ['C:\\WMS Repository\\Warehouse Management System', 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.3\\helpers\\pydev', 'C:\\WMS Repository\\Warehouse Management System', 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.3\\helpers\\pydev', 'C:\\Users\\heast\\.PyCharm2018.1\\system\\cythonExtensions', 'C:\\miniconda3\\envs\\django\\python36.zip', 'C:\\miniconda3\\envs\\django\\DLLs', 'C:\\miniconda3\\envs\\django\\lib', 'C:\\miniconda3\\envs\\django', 'C:\\Users\\heast\\AppData\\Roaming\\Python\\Python36\\site-packages', 'C:\\miniconda3\\envs\\django\\lib\\site-packages', 'C:\\Program Files\\JetBrains\\PyCharm ' '2017.3.3\\helpers\\pycharm_matplotlib_backend'] Server time: Mon, 16 Jul 2018 14:58:30 -0400 Environment: Request Method: POST Request URL: http://localhost:8000/utils/box-optimization/add-items/118 Django Version: 2.0.5 Python Version: 3.6.5 Installed Applications: ['item.apps.ItemConfig', 'inventory.apps.InventoryConfig', 'fulfillment.apps.FulfillmentConfig', 'manifest.apps.ManifestConfig', 'order.apps.OrderConfig', 'utils.apps.UtilsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback: File "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\exception.py" in inner 35. response = get_response(request) File "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in _get_response 128. response = self.process_exception_by_middleware(e, request) File "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in _get_response 126. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\base.py" in view 69. return self.dispatch(request, *args, **kwargs) File "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\base.py" in dispatch 89. return handler(request, *args, **kwargs) File "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" in post 172. return super().post(request, *args, **kwargs) File "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" in post 141. if form.is_valid(): File "C:\miniconda3\envs\django\lib\site-packages\django\forms\forms.py" in is_valid 179. return self.is_bound and not self.errors File "C:\miniconda3\envs\django\lib\site-packages\django\forms\forms.py" in errors 174. self.full_clean() File "C:\miniconda3\envs\django\lib\site-packages\django\forms\forms.py" in full_clean 378. self._post_clean() File "C:\miniconda3\envs\django\lib\site-packages\django\forms\models.py" in _post_clean 396. self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude) File "C:\miniconda3\envs\django\lib\site-packages\django\forms\models.py" in construct_instance 60. f.save_form_data(instance, cleaned_data[f.name]) File "C:\miniconda3\envs\django\lib\site-packages\django\db\models\fields\__init__.py" in save_form_data 838. setattr(instance, self.name, data) File "C:\miniconda3\envs\django\lib\site-packages\django\db\models\fields\related_descriptors.py" in __set__ 197. self.field.remote_field.model._meta.object_name, Exception Type: ValueError at /utils/box-optimization/add-items/118 Exception Value: Cannot assign "'515874'": "ItemsTestCollection.item" must be a "Item" instance. On Monday, July 16, 2018 at 1:14:41 PM UTC-4, Matthew Pava wrote: > > This StackOverflow question may help you: > > > https://www.google.com/search?q=django+clean_fields+not+called&oq=django+clean_field+not+&aqs=chrome.1.69i57j0.7599j0j4&sourceid=chrome&ie=UTF-8 > > > > Basically this: > > For any field, if the Field.clean() method raises a ValidationError, any > field-specific cleaning method is not called. However, the cleaning methods > for all remaining fields are still executed. > > > > item should already return an instance of an Item object without your > clean method. > > > > *From:* django...@googlegroups.com <javascript:> [mailto: > django...@googlegroups.com <javascript:>] *On Behalf Of * > clavie...@gmail.com <javascript:> > *Sent:* Monday, July 16, 2018 11:27 AM > *To:* Django users > *Subject:* Re: help with get_form_kwargs > > > > I would actually prefer to override clean(), but CreateView doesn't appear > to have a clean() method that I can override. I did make a ModelForm to use > with the CreateView, but the clean_item method I defined there never gets > called--breakpoints and print statements are all skipped, so I don't even > have any stack trace information because nothing actually breaks. I've > looked through the source code and I still don't see how CreateView cleans > its data. > > > > class AddItem(forms.ModelForm): > > class Meta: > model = ItemsTestCollection > fields = ['item', 'qty', 'case'] > > def clean_item(self): > print("will it print anything?") > > *# Answer: nope, didn't print anything. *item_num = > self.cleaned_data['item'] > actual_item = Item.objects.get(item_number=item_num) > return actual_item.id > > > > I'm sure I've overlooked something simple, but meanwhile I'm looking for > any kind of workaround. But thank you for the suggestion! I wish I knew how > to implement it. > > On Monday, July 16, 2018 at 11:46:39 AM UTC-4, Matthew Pava wrote: > > I would alter user input in the clean methods. > > https://docs.djangoproject.com/en/2.0/ref/forms/validation/ > > > > > > *From:* django...@googlegroups.com [mailto:django...@googlegroups.com] *On > Behalf Of *clavie...@gmail.com > *Sent:* Monday, July 16, 2018 10:28 AM > *To:* Django users > *Subject:* help with get_form_kwargs > > > > I have a CreateView in which I need to alter the user input. I may have > found a way to do so using get_form_kwargs, but I'm puzzled by a couple of > things: > > > > I know that kwargs['data'] is a QueryDict, which is immutable. So I tried > the doc's QueryDict.copy() recommendation: > > def get_form_kwargs(self): > kwargs = super().get_form_kwargs() > clone = kwargs['data'].copy() > > *# clone = copy(kwargs['data']) *item_num = clone['item'] > actual_item = Item.objects.get(item_number=item_num) > clone['item'] = str(actual_item.id) > > *# data.update({'item': actual_item}) *kwargs['data'] = clone > return kwargs > > > > It appears to work just fine until the return statement. I can step > through every line and see the values change exactly the way I want them to > change. By the time I get to the return statement, `clone`--which is a copy > of kwargs['data']--is a QueryDict that contains the correct information. > However, the program crashes with a KeyError after `kwargs` is returned, > saying that kwargs['data'] doesn't exist. In the following stack trace, > line 62 is the second line of the method (clone = kwargs['data'].copy()). > > > KeyError at /utils/box-optimization/add-items/115 > > 'data' > > *Request Method:* > > GET > > *Request URL:* > > http://localhost:8000/utils/box-optimization/add-items/115 > > *Django Version:* > > 2.0.5 > > *Exception Type:* > > KeyError > > *Exception Value:* > > 'data' > > *Exception Location:* > > C:\WMS Repository\Warehouse Management System\utils\views.py in > get_form_kwargs, line 62 > > *Python Executable:* > > C:\miniconda3\envs\django\python.exe > > *Python Version:* > > 3.6.5 > > *Python Path:* > > ['C:\\WMS Repository\\Warehouse Management System', > > 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.3\\helpers\\pydev', > > 'C:\\WMS Repository\\Warehouse Management System', > > 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.3\\helpers\\pydev', > > 'C:\\Users\\heast\\.PyCharm2018.1\\system\\cythonExtensions', > > 'C:\\miniconda3\\envs\\django\\python36.zip', > > 'C:\\miniconda3\\envs\\django\\DLLs', > > 'C:\\miniconda3\\envs\\django\\lib', > > 'C:\\miniconda3\\envs\\django', > > 'C:\\Users\\heast\\AppData\\Roaming\\Python\\Python36\\site-packages', > > 'C:\\miniconda3\\envs\\django\\lib\\site-packages', > > 'C:\\Program Files\\JetBrains\\PyCharm ' > > '2017.3.3\\helpers\\pycharm_matplotlib_backend'] > > *Server time:* > > Mon, 16 Jul 2018 11:16:38 -0400 > > Environment: > > > > > > Request Method: GET > > Request URL: http://localhost:8000/utils/box-optimization/add-items/115 > > > > Django Version: 2.0.5 > > Python Version: 3.6.5 > > Installed Applications: > > ['item.apps.ItemConfig', > > 'inventory.apps.InventoryConfig', > > 'fulfillment.apps.FulfillmentConfig', > > 'manifest.apps.ManifestConfig', > > 'order.apps.OrderConfig', > > 'utils.apps.UtilsConfig', > > 'django.contrib.admin', > > 'django.contrib.auth', > > 'django.contrib.contenttypes', > > 'django.contrib.sessions', > > 'django.contrib.messages', > > 'django.contrib.staticfiles'] > > Installed Middleware: > > ['django.middleware.security.SecurityMiddleware', > > 'django.contrib.sessions.middleware.SessionMiddleware', > > 'django.middleware.common.CommonMiddleware', > > 'django.middleware.csrf.CsrfViewMiddleware', > > 'django.contrib.auth.middleware.AuthenticationMiddleware', > > 'django.contrib.messages.middleware.MessageMiddleware', > > 'django.middleware.clickjacking.XFrameOptionsMiddleware'] > > > > > > > > Traceback: > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\exception.py" > > in inner > > 35. response = get_response(request) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\base.py" > in _get_response > > 128. response = self.process_exception_by_middleware(e, > request) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\core\handlers\base.py" > in _get_response > > 126. response = wrapped_callback(request, > *callback_args, **callback_kwargs) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\base.py" > in view > > 69. return self.dispatch(request, *args, **kwargs) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\base.py" > in dispatch > > 89. return handler(request, *args, **kwargs) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" > in get > > 168. return super().get(request, *args, **kwargs) > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" > in get > > 133. return self.render_to_response(self.get_context_data()) > > > > File "C:\WMS Repository\Warehouse Management System\utils\views.py" in > get_context_data > > 93. context = super().get_context_data() > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" > in get_context_data > > 66. kwargs['form'] = self.get_form() > > > > File > "C:\miniconda3\envs\django\lib\site-packages\django\views\generic\edit.py" > in get_form > > 33. return form_class(**self.get_form_kwargs()) > > > > File "C:\WMS Repository\Warehouse Management System\utils\views.py" in > get_form_kwargs > > 62. clone = kwargs['data'].copy() > > > > Exception Type: KeyError at /utils/box-optimization/add-items/115 > > Exception Value: 'data' > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users...@googlegroups.com. > To post to this group, send email to djang...@googlegroups.com. > Visit this group at https://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/d1cddae6-72a7-46b3-a6b1-40fcdc22ae93%40googlegroups.com > > <https://groups.google.com/d/msgid/django-users/d1cddae6-72a7-46b3-a6b1-40fcdc22ae93%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users...@googlegroups.com <javascript:>. > To post to this group, send email to djang...@googlegroups.com > <javascript:>. > Visit this group at https://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/e7b64bc4-8c00-4db8-aada-e3f2a4751b7e%40googlegroups.com > > <https://groups.google.com/d/msgid/django-users/e7b64bc4-8c00-4db8-aada-e3f2a4751b7e%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ebb14010-ff30-4df7-a90f-8d1d9b577efb%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.