Установка UpdateView в Django с формой, у которой настроен метод __init__
Когда я использую UpdateView в Django с формой, у которой метод init настроен для настройки кверисетов ModelMultipleChoiceField не загружает начальные значения экземпляра?
Сначала немного контекста: я делаю приложение, которое управляет документами, связанными с субпорталами, для этого каждый субпортал имеет связанные группы служб и зависимости.
Мне нужно, чтобы при загрузке документа он мог быть классифицирован по группам служб и зависимостям, которые связаны только с субпорталом. Я достиг этого, используя метод init в формах.
Проблема в том, что когда мне нужно обновить данные документа, начальные значения модели не появляются.
Я показываю коды
Models.py
class ServiceGroup(models.Model):
subportal = models.ForeignKey(Subportal, null=True, blank=True, on_delete=models.CASCADE)
title = models.CharField(max_length=150, null=False, blank=False)
description = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Dependence(models.Model):
subportal = models.ForeignKey(Subportal, null=True, blank=True, on_delete=models.CASCADE)
title = models.CharField(max_length=150, null=False, blank=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class SubportalDocument(models.Model):
def get_upload_to(instance, filename):
return '{}/documents/{}'.format(instance.subportal.title, filename)
subportal = models.ForeignKey(Subportal, null=True, blank=True, on_delete=models.CASCADE)
showcategory = models.OneToOneField(ShowCategory, null=True, blank=True, on_delete=models.CASCADE)
title = models.CharField(max_length=150, null=False, blank=False)
file = models.FileField(upload_to=get_upload_to, null=False, blank=False)
review_date = models.DateField(null=False, blank=True)
review_nro = models.IntegerField(null=False, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
dependences = models.ManyToManyField(Dependence, related_name='dependencesdoc', blank=True)
servicegroups = models.ManyToManyField(ServiceGroup, related_name='servicegroupsdoc', blank=True)
def __str__(self):
return self.title
Forms.py
class SubportalDocumentForm(forms.ModelForm):
class Meta:
model = SubportalDocument
exclude = ['subportal', 'created_at', 'status']
labels = {
'showcategory':'Categoría de Despliegue:',
'title':'Nombre del Documento:',
'file':'Cargar el archivo:',
'review_nro':'Número de Revisión:',
'review_date':'Fecha de Revisión:',
}
widgets = {
'showcategory':forms.Select(attrs={'class':'form-select'}),
'title':forms.TextInput(attrs={'class':'form-control'}),
'file':forms.FileInput(attrs={'class':'form-control'}),
'review_nro': forms.NumberInput(attrs={'class':'form-control'}),
'review_date': forms.DateInput(format=('%d/%m/%Y'),
attrs={'class':'form-control',
'type':'date'}),
}
servicegroups = forms.ModelMultipleChoiceField(
label='Grupos de Servicios:',
queryset=None,
widget=forms.CheckboxSelectMultiple,
)
dependences = forms.ModelMultipleChoiceField(
label='Dependencias:',
queryset=None,
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
self.subportal = kwargs.pop('subportal')
super(SubportalDocumentForm, self).__init__(*args, **kwargs)
self.fields['servicegroups'].queryset = ServiceGroup.objects.filter(
subportal=self.subportal)
self.fields['dependences'].queryset = Dependence.objects.filter(
subportal=self.subportal)
self.fields['showcategory'].queryset = ShowCategory.objects.filter(
subportal=self.subportal)
self.fields['servicegroups'].widget.attrs.update({
'class': 'form-check-input',
})
self.fields['dependences'].widget.attrs.update({
'class': 'form-check-input',
})
Views.py
class SubportalDocumentUpdateView(UpdateView):
model = SubportalDocument
form_class = SubportalDocumentForm
template_name = 'portal_manager/create_document.html'
def get_form_kwargs(self, *args, **kwargs):
subportal_id = self.get_object().subportal_id
subportal = get_object_or_404(Subportal, id=subportal_id)
kwargs = {
"subportal": subportal,
}
return kwargs
def dispatch(self, request, *args, **kwargs):
id = self.get_object().subportal_id
self.get_form().fields['servicegroups'].queryset = ServiceGroup.objects.filter(subportal_id=id)
self.get_form().fields['dependences'].queryset = Dependence.objects.filter(subportal_id=id)
return super(SubportalDocumentUpdateView, self).dispatch(request, *args, **kwargs)
def get_success_url(self):
id = self.get_object().subportal_id
return reverse_lazy('portal_manager:admin_subportal', kwargs={'id': id})
Urls.py
path('modificar-documento/<int:pk>', views.SubportalDocumentUpdateView.as_view(), name='update_document'),
В результате я получаю следующее изображение формы без начальных значений
Теперь, если я не использую метод init в формах для фильтрации групп служб и зависимостей по субпорталу, я получаю начальные значения.
forms.py not init
class SubportalDocumentForm(forms.ModelForm):
class Meta:
model = SubportalDocument
exclude = ['subportal', 'created_at', 'status']
labels = {
'showcategory':'Categoría de Despliegue:',
'title':'Nombre del Documento:',
'file':'Cargar el archivo:',
'review_nro':'Número de Revisión:',
'review_date':'Fecha de Revisión:',
}
widgets = {
'showcategory':forms.Select(attrs={'class':'form-select'}),
'title':forms.TextInput(attrs={'class':'form-control'}),
'file':forms.FileInput(attrs={'class':'form-control'}),
'review_nro': forms.NumberInput(attrs={'class':'form-control'}),
'review_date': forms.DateInput(format=('%d/%m/%Y'),
attrs={'class':'form-control',
'type':'date'}),
}
servicegroups = forms.ModelMultipleChoiceField(
label='Grupos de Servicios:',
queryset=ServiceGroup.objects.all(),
widget=forms.CheckboxSelectMultiple,
)
dependences = forms.ModelMultipleChoiceField(
label='Dependencias:',
queryset=Dependence.objects.all(),
widget=forms.CheckboxSelectMultiple,
)
Ajust Views.py
class SubportalDocumentUpdateView(UpdateView):
model = SubportalDocument
form_class = SubportalDocumentForm
template_name = 'portal_manager/create_document.html'
def dispatch(self, request, *args, **kwargs):
id = self.get_object().subportal_id
self.get_form().fields['servicegroups'].queryset = ServiceGroup.objects.filter(subportal_id=id)
self.get_form().fields['dependences'].queryset = Dependence.objects.filter(subportal_id=id)
return super(SubportalDocumentUpdateView, self).dispatch(request, *args, **kwargs)
def get_success_url(self):
id = self.get_object().subportal_id
return reverse_lazy('portal_manager:admin_subportal', kwargs={'id': id})
Изображение с ожидаемым результатом, но с фильтрацией групп служб и зависимостей
Если кто-то может помочь мне или дать мне подсказку о том, что происходит, я был бы очень признателен, я уже долгое время исследую и не могу получить ответ.