I have a model in Django, Model A. Very typical, it has various fields, some choice fields, some boolean, some character fields.
I have another model, Model B, in this model, the intended functionality is that in Django Admin the first field is a select, where the user can choose from any field that exists in Model A. This is implemented already. What I need help figuring out is how to make the second field of Model B Mimic the options of Model A.
If Model A has a choice field named 'Meat', and it's choices are 'Beef, Turkey, and Chicken', If the user adding an entry to Model B selects 'Meat' in field 1, field 2 will be a choice field with 'Beef, Turkey, and Chicken'.
If Model A has a character field named 'Anything Goes', If the user adding an entry to Model B selects 'Anything Goes' in field 1, field 2 will be a standard text-input field.
If Model A is a boolean field named 'Yes/No', If the user adding an entry to Model B selects 'Yes/No' in field 1, field 2 will be a standard boolean select field.
I believe the main thing I'm looking for help with is having a way to write custom code for a chained select/dependent drop down that doesn't involve pre-implemented many-to-many or foreign-key relationships.
I'm not sure what libraries are currently supported in Django 2 that would be a good starting point, or how I might go about writing some sort of ajax myself that works with the admin.
-- EDIT --
It looks like the best way to handle this is using django-autocomplete-light.
URLS
re_path(r'^post-new-text/$',
views.PostNewTextView.as_view(),
name='post-new-text')
FORMS
class PostNormalizeForm(forms.ModelForm):
class Meta:
model = PostNormalize
widgets = {
'new_text': autocomplete.ListSelect2(url='post-new-text', forward=['target_field', 'check_field'])
}
fields = ('__all__')
VIEWS
class PostNewTextView(autocomplete.Select2ListView):
def get_list(self):
target_field = self.forwarded.get('target_field', None)
check_field = self.forwarded.get('check_field', None)
if target_field == 'self':
target_field = check_field
choice_list = [str(choice[0]) for choice in Post._meta.get_field(target_field).choices]
return choice_list
Basically, you write your own list based return for an autocomplete.Select2ListView using forwarded inputs. In the example Post is the model A, and PostNormalize is the model B.
At this point what's left to figure out, is that if the forwarded field is not a choice field, how to allow free-entry in the new_text field.