创建子表单并同时修改父表单,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)