У меня есть установка с моделями, которые я не встречал в своих исследованиях. Это модель со сквозной таблицей отношений, которая является отношением OneToOne.Django ManyToManyField, который указывает промежуточную модель. Через отношение OneToOneField
Проблема заключается в том, что интерфейс администратора отлично работает при настройке оговорок в форме.
class AgentForm(forms.ModelForm):
class Meta:
model = Agent
Но создание базового ModelForm приводит к ошибке:
AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use podman.BladeReservation's Manager instead.
models.py
class Node(models.Model):
name = models.CharField(_('Name'), help_text=_('A name for the node.'), max_length=128)
hostname = models.CharField(
verbose_name=_('Hostname'),
max_length=255,
blank=True, null=True
)
class Meta:
abstract = True
ordering = ['name', 'hostname']
class Blade(Node):
serial_number = models.CharField(_('Serial Number'), max_length=255, unique=True)
uuid = models.CharField(
verbose_name=_('UUID'),
help_text=_('Node UUID'),
max_length=50,
null=True, blank=True
)
...
class Agent(models.Model):
name = models.CharField(_('Name'), max_length=128, help_text=_('This name is a friendly handle for humans.'))
slug = models.SlugField(
verbose_name=_(u'Slug'),
help_text=_('Uri identifier. This name is the lookup key for Automation'),
max_length=100,
unique=True
)
...
blades = models.ManyToManyField('podman.Blade', related_name='blades', through='podman.BladeReservation')
...
class BladeReservation(models.Model):
blade = models.OneToOneField('podman.Blade')
agent = models.ForeignKey('podman.Agent')
reserved_until = models.DateTimeField(null=True, blank=True)
admin.py
class AgentAdmin(CompareNoDuplicates):
prepopulated_fields = {'slug': ('name',)}
inlines = [BladeReservationInline]
filter_horizontal = ('blades',)
list_display_links = ('__str__',)
preserve_filters = True
class BladeReservationInline(admin.TabularInline):
model = BladeReservation
def get_formset(self, request, obj=None, **kwargs):
kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj)
return super(BladeReservationInline, self).get_formset(request, obj, **kwargs)
def formfield_for_dbfield(self, db_field, **kwargs):
agent = kwargs.pop('obj', None)
formfield = super(BladeReservationInline, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == "blade" and agent:
formfield.queryset = formfield.queryset.filter(chassis__pod__in=[p for p in agent.container.pods.all()])
return formfield
Мой текущий трек делает WizardView только, чтобы получить пользовательский поток формы, но его не идеально. Любые идеи были бы хорошы.
Показать часть ваших взглядов там, где вы имеете дело с формой – chem1st