I'm playing with django forms a little, and trying to check if all form fields correspond to a field of a model through name-checking, this is being done in form constructor function, but I find silly to make such a check on every form instance made so, I would like to do so but on form class. I came to think that to attain it I would need models to be loaded first in django and maybe... to listen to a signal and wait for executing the code once they are loaded, i read through Django Signal doc, but i'm not sure if code will fulfill per my purpose. Is there a way to do it??. Any help is welcome.
What you'll see below on the code section is a form with a basic filtering functionality.
FORM CODE :
class NoticeFilter(forms.ModelForm):
name = forms.CharField(max_length=12, required=False)
def checkfields(self):
#Check that the form fields are a subset of the model fields
#Granting that every field defined here corresponds only to a model field
#and has its same name, no aditional input.
list_ = []
field_names = set(boundfield.name for boundfield in self)
for model_field in self.__class__.Meta.model._meta.get_fields():
list_.append(model_field.name)
list_ = set(list_)
if field_names.issubset(list_):
print('You are good to go')
else:
print('You have one or more fields whose name doesnt match with any of the corresponding model fields.')
def __init__(self, *args, **kwargs):
#check function, raises an error if put before __init__
self.checkfields()
#Pop a queryset provided for filtering purposes through form field input
queryset = kwargs.pop('queryset', None)
super().__init__(*args, **kwargs)
if not queryset:
self.queryset = self.__class__.Meta.model.objects.all()
else:
self.queryset = queryset
dict_ = {}
if self.is_valid():
#if form is valid then program can proceed to filter
for field in self:
#make a dict from boundfields key, value pair, to pass it as kwargs
#to queryset filter method
dict_.setdefault(field.name, field.value())
try:
self.qs = self.queryset.filter(**dict_)
except FieldError:
raise FieldError('You have inserted a set of fields which differ in name according to the names of the model fields you are using for this form.')
class Meta:
model = Notice
fields = (
'title',
)
widgets = {
'tag' : autocomplete.ModelSelect2Multiple(url='tag-autocomplete'),
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…