У меня была похожая проблема. Цель состояла в том, чтобы иметь класс, который позволял бы определенным полям принимать значение группы. Приведенный ниже код вводит эти функции в вашу модель:
- Если вы хотите, чтобы поле унаследовало значение группы, вам нужно всего лишь создать еще один BooleanField с именем «inherit_group _».
- Если вы установите значение наследуемого поля, для значения «inherit_group_» автоматически устанавливается значение «Ложь» (поскольку вы установили явное значение).
- Если вы установите для свойства «attribute_group_» значение «Истина», значение соответствующего поля возвращается обратно к значению группы.
- Все остальное обрабатывается, включая сохранение и инициализацию.
Одно предупреждение - если вы используете ModelForm с этой моделью, вам необходимо переопределить функцию сохранения, чтобы все атрибуты «attributeit_group_» устанавливались последними, поскольку, когда установлены соответствующие поля местоположения, «attributeit_group_» будет установите значение False, как описано выше. Этот код также приведен ниже. Вероятно, все это лучше всего решить путем создания новых классов - InheritableModel и InheritableModelForm. Хотя мне было лень это делать:).
Вот код для модели:
_inheritable_fields = []
def __init__(self, *args, **kwargs):
super(Location, self).__init__(*args, **kwargs)
# Change iheritable field values to group value if current value is
# None
self._inheritable_fields = [
fname for fname in dir(self)
if hasattr(self, 'inherit_group_%s' % fname)]
# Make sure that all fields are in the correct state given the
# inherit_group values
[setattr(self, 'inherit_group_%s' % fname, getattr(self,
'inherit_group_%s' % fname))
for fname in self._inheritable_fields]
def __setattr__(self, name, val):
super(Location, self).__setattr__(name, val)
if name == "group" and val:
# A new group was specified. Update all fields that are currently
# inheriting from the group
[models.Model.__setattr__(self, fname, getattr(self.group, fname))
for fname in self._inheritable_fields
if getattr(self, 'inherit_group_%s' % fname)]
elif name in self._inheritable_fields:
# An inheritable field value changed. Update its inheritance state
models.Model.__setattr__(self, 'inherit_group_%s' % name, False)
elif name.startswith('inherit_group_'):
field_name = re.sub('^inherit_group_', '', name)
if val and field_name in self._inheritable_fields:
# An inheritance state (e.g., inherit_group_name) was changed.
# Change value back to group value
if hasattr(self, 'group'):
models.Model.__setattr__(self, field_name,
getattr(self.group, field_name))
else:
models.Model.__setattr__(self, field_name, None)
def save(self, *args, **kwargs):
# Set all fields using the inherited value to None for DB storage.
val_from_group = [
fname for fname in self._inheritable_fields
if getattr(self, 'inherit_group_%s' % fname)]
[models.Model.__setattr__(self, fname, None) for fname in val_from_group]
super(Location, self).save(*args, **kwargs)
# Return the fields changed above back to the group values.
[models.Model.__setattr__(self, fname, getattr(self.group, fname))
for fname in self._inheritable_fields
if getattr(self, 'inherit_group_%s' % fname)]
Вот код для ModelForm:
def save(self, commit=True):
location = super(LocationForm, self).save(commit=False)
# location.inherit_group_x has to be set last as it'll be set to
# False when it's associated field is set
[setattr(location, 'inherit_group_%s' % fname,
self.cleaned_data['inherit_group_%s' % fname])
for fname in location._inheritable_fields]
if commit:
location = super(LocationForm, self).save()
return location