创建子表单并同时修改父表单,Django
Create a child form and modify parent at same time, Django
我有两个模型与父子外键连接,我可以创建子数据并同时修改父模型中存在的字段。
感谢您的帮助
'''
models.py
class Richieste(models.Model):
SCELTA_1 = [
('Estero', 'Estero'),
('Italia', 'Italia'),
]
STATO = [
('In lavorazione', 'In lavorazione'),
('Chiuso esito POSITIVO', 'Chiuso esito POSITIVO'),
('Chiuso esito NEGATIVO', 'Chiuso esito NEGATIVO'),
]
TIPO_PRODOTTO = [
('Esterno', 'Esterno'),
('Interno', 'Interno'),
]
titolo = models.CharField(max_length=100, help_text='Indica Argomento/Agenzia richiedente')
contenuto = models.TextField()
data_creazione = models.DateTimeField(default=timezone.now)
scelta_1 = models.CharField(max_length=50, choices=SCELTA_1, help_text='ITALI/ESTERO', verbose_name = "provenienza")
stato = models.CharField(max_length=50, choices=STATO, default='In lavorazione' , blank = True, help_text='Stato richiesta')
tipo_prodotto = models.CharField(max_length=50, choices=TIPO_PRODOTTO, blank = False, help_text='Esterno/Interno')
protocollo = models.IntegerField(blank=True, null=True) #default='SOME STRING'
allegato = models.FileField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True, verbose_name = "allega documenti")
allegato_img = models.ImageField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True, verbose_name = "allega immagini")
autore = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
template = '{0.titolo} {0.autore} '
return template.format(self)
def get_absolute_url(self):
return reverse('speciali-home')
class Discussione(models.Model):
risposta = models.ForeignKey(Richieste, on_delete=models.CASCADE)
contenuto = models.TextField()
data_risposta = models.DateTimeField(default=timezone.now)
allegato = models.FileField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True)
elaboratore = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
template = '{0.risposta} {0.elaboratore} '
return template.format(self)
'''
当我创建一个 Discussione 表单时一切正常但我想以相同的形式更改父模型 'Richieste'
的 'Stato'
'''
forms.py
class DiscRispModelForm(forms.ModelForm):
#stato = forms.ModelChoiceField(queryset=Richieste.objects.all())
class Meta:
model = Discussione
fields = '__all__'
def __init__(self, risposta_id=None, elaboratore_id=None, *args, **kwargs):
super(DiscRispModelForm, self).__init__( *args, **kwargs)
self.fields["risposta"].widget = forms.HiddenInput()
self.fields["elaboratore"].widget = forms.HiddenInput()
self.fields["data_risposta"].widget = forms.HiddenInput()
if risposta_id:
self.fields['risposta'].initial = risposta_id
if elaboratore_id:
self.fields['elaboratore'].initial = elaboratore_id
'''
'''
views.py
class DiscCreateView(LoginRequiredMixin, CreateView):
model = Discussione
template_name = 'discussione_nuova.html'
form_class = DiscRispModelForm
def get_context_data(self, **kwargs):
# we need to overwrite get_context_data
# to make sure that our formset is rendered
data = super().get_context_data(**kwargs)
if self.request.POST:
data["children"] = RichiesteForm(self.request.POST)
else:
data["children"] = RichiesteForm()
return data
def form_valid(self, form):
context = self.get_context_data()
children = context["children"]
self.object = form.save()
if children.is_valid():
children.instance = self.object
children.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('speciali-richiesta-singola', kwargs={'pk': self.kwargs.get('pk')})
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs(*args, **kwargs)
kwargs['risposta_id'] = self.kwargs.get('pk')
kwargs['elaboratore_id'] = self.request.user
return kwargs
'''
您必须覆盖子模型的 save() 方法并根据更改修改父模型。如果没有您的模型示例,我无法给您举个例子。
编辑:
在您的情况下,您可以在 ModelForm 中添加一个额外的字段并覆盖 ModelForm 的 save()
方法:
class DiscRispModelForm(forms.ModelForm):
stato = forms.ChoiceField(choices = [('In lavorazione', 'In lavorazione'),('Chiuso esito POSITIVO', 'Chiuso esito POSITIVO'),('Chiuso esito NEGATIVO', 'Chiuso esito NEGATIVO')])
class Meta:
model = Discussione
fields = '__all__'
def __init__(self, risposta_id=None, elaboratore_id=None, *args, **kwargs):
super(DiscRispModelForm, self).__init__( *args, **kwargs)
self.fields["risposta"].widget = forms.HiddenInput()
self.fields["elaboratore"].widget = forms.HiddenInput()
self.fields["data_risposta"].widget = forms.HiddenInput()
if risposta_id:
self.fields['risposta'].initial = risposta_id
if elaboratore_id:
self.fields['elaboratore'].initial = elaboratore_id
def save(self, commit=True):
# do something with self.cleaned_data['stato'] like:
self.instance.risposta.stato = self.cleaned_data['stato']
self.instance.risposta.save()
return super(DiscRispModelForm, self).save(commit=commit)
我有两个模型与父子外键连接,我可以创建子数据并同时修改父模型中存在的字段。 感谢您的帮助
''' models.py
class Richieste(models.Model):
SCELTA_1 = [
('Estero', 'Estero'),
('Italia', 'Italia'),
]
STATO = [
('In lavorazione', 'In lavorazione'),
('Chiuso esito POSITIVO', 'Chiuso esito POSITIVO'),
('Chiuso esito NEGATIVO', 'Chiuso esito NEGATIVO'),
]
TIPO_PRODOTTO = [
('Esterno', 'Esterno'),
('Interno', 'Interno'),
]
titolo = models.CharField(max_length=100, help_text='Indica Argomento/Agenzia richiedente')
contenuto = models.TextField()
data_creazione = models.DateTimeField(default=timezone.now)
scelta_1 = models.CharField(max_length=50, choices=SCELTA_1, help_text='ITALI/ESTERO', verbose_name = "provenienza")
stato = models.CharField(max_length=50, choices=STATO, default='In lavorazione' , blank = True, help_text='Stato richiesta')
tipo_prodotto = models.CharField(max_length=50, choices=TIPO_PRODOTTO, blank = False, help_text='Esterno/Interno')
protocollo = models.IntegerField(blank=True, null=True) #default='SOME STRING'
allegato = models.FileField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True, verbose_name = "allega documenti")
allegato_img = models.ImageField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True, verbose_name = "allega immagini")
autore = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
template = '{0.titolo} {0.autore} '
return template.format(self)
def get_absolute_url(self):
return reverse('speciali-home')
class Discussione(models.Model):
risposta = models.ForeignKey(Richieste, on_delete=models.CASCADE)
contenuto = models.TextField()
data_risposta = models.DateTimeField(default=timezone.now)
allegato = models.FileField(upload_to='uploads//%Y/%m/%d/', blank = True, null=True)
elaboratore = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
template = '{0.risposta} {0.elaboratore} '
return template.format(self)
''' 当我创建一个 Discussione 表单时一切正常但我想以相同的形式更改父模型 'Richieste'
的 'Stato'''' forms.py
class DiscRispModelForm(forms.ModelForm):
#stato = forms.ModelChoiceField(queryset=Richieste.objects.all())
class Meta:
model = Discussione
fields = '__all__'
def __init__(self, risposta_id=None, elaboratore_id=None, *args, **kwargs):
super(DiscRispModelForm, self).__init__( *args, **kwargs)
self.fields["risposta"].widget = forms.HiddenInput()
self.fields["elaboratore"].widget = forms.HiddenInput()
self.fields["data_risposta"].widget = forms.HiddenInput()
if risposta_id:
self.fields['risposta'].initial = risposta_id
if elaboratore_id:
self.fields['elaboratore'].initial = elaboratore_id
'''
''' views.py
class DiscCreateView(LoginRequiredMixin, CreateView):
model = Discussione
template_name = 'discussione_nuova.html'
form_class = DiscRispModelForm
def get_context_data(self, **kwargs):
# we need to overwrite get_context_data
# to make sure that our formset is rendered
data = super().get_context_data(**kwargs)
if self.request.POST:
data["children"] = RichiesteForm(self.request.POST)
else:
data["children"] = RichiesteForm()
return data
def form_valid(self, form):
context = self.get_context_data()
children = context["children"]
self.object = form.save()
if children.is_valid():
children.instance = self.object
children.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('speciali-richiesta-singola', kwargs={'pk': self.kwargs.get('pk')})
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs(*args, **kwargs)
kwargs['risposta_id'] = self.kwargs.get('pk')
kwargs['elaboratore_id'] = self.request.user
return kwargs
'''
您必须覆盖子模型的 save() 方法并根据更改修改父模型。如果没有您的模型示例,我无法给您举个例子。
编辑:
在您的情况下,您可以在 ModelForm 中添加一个额外的字段并覆盖 ModelForm 的 save()
方法:
class DiscRispModelForm(forms.ModelForm):
stato = forms.ChoiceField(choices = [('In lavorazione', 'In lavorazione'),('Chiuso esito POSITIVO', 'Chiuso esito POSITIVO'),('Chiuso esito NEGATIVO', 'Chiuso esito NEGATIVO')])
class Meta:
model = Discussione
fields = '__all__'
def __init__(self, risposta_id=None, elaboratore_id=None, *args, **kwargs):
super(DiscRispModelForm, self).__init__( *args, **kwargs)
self.fields["risposta"].widget = forms.HiddenInput()
self.fields["elaboratore"].widget = forms.HiddenInput()
self.fields["data_risposta"].widget = forms.HiddenInput()
if risposta_id:
self.fields['risposta'].initial = risposta_id
if elaboratore_id:
self.fields['elaboratore'].initial = elaboratore_id
def save(self, commit=True):
# do something with self.cleaned_data['stato'] like:
self.instance.risposta.stato = self.cleaned_data['stato']
self.instance.risposta.save()
return super(DiscRispModelForm, self).save(commit=commit)