Assign a foreign key from one form to another in django and redirect with reverse_lazy

0

I have 2 test models, Model1 and Model2. Model2 has the OneToOneField key to Model1, but I can not assign the Model1_id to Model2_id to keep the relationship of the models, I do not know how to access that data from the views.py to assign it in form_is_valid, when I save the first form, I can not send it with reverse_lazy, since I must pass the pk, if I enter it manually to URL, with a select I can assign it, but I think that should be done in the backend

My models are from:

apps/formularios/models.py

class Modelo1(models.Model):
    nombre = models.CharField(max_length=20)
    apellidos = models.CharField(max_length=50)


class Modelo2(models.Model):
    relacionModelo1 = models.OneToOneField(Modelo1, blank=False, null=False, on_delete=models.CASCADE)
    curp = models.CharField(max_length=18)
    nacionalidad = models.CharField(max_length=50)

my forms

apps/forms.py

class Modelo1Form(forms.ModelForm):
    class Meta:
        model = Modelo1

        fields = ['nombre', 'apellidos']

        labels = {
            'nombre': 'Nombre(s)',
            'apellidos': 'Apellidos',
        }

        widgets = {
            'nombre': forms.TextInput(),
            'apellidos': forms.TextInput(),
        }


class Modelo2Form(forms.ModelForm):
    class Meta:
        model = Modelo2
        fields = ['relacionModelo1', 'curp', 'nacionalidad']

        labels = {
            'curp': 'CURP',
            'nacionalidad': 'Nacionalidad',
        }

        widgets = {
            'relacionModelo1': forms.HiddenInput(),
            'curp': forms.TextInput(),
            'nacionalidad': forms.TextInput(),
        }

My views.py

class Model1CreateView(CreateView):
    model = Modelo1
    form_class = Modelo1Form
    template_name = 'form.html'
    success_url = reverse_lazy('agregar:formulario2')
    #no se como pasarle la pk a la siguiente página

class Model2CreateView(CreateView):
    #no sé como asiganrle la pk del formulario1 al campo relacionModelo1
    model = Modelo2
    form_class = Modelo2Form
    template_name = 'form.html'
    success_url = reverse_lazy('agregar:formulario1')

Project URL

from django.conf.urls import url

import views

app_name = "agregar"

urlpatterns = [
    url(r'nuevo1/$', views.Model1CreateView.as_view(), name='formualario1'),
    url(r'nuevo2/(?P<pk>\d+)/$', views.Model2CreateView.as_view(), name='formulario2'),
]

    
asked by Kuroi 05.03.2018 в 20:33
source

1 answer

1

One way would be to write the method form_valid of each view you have

  • In the view Model1CreateView : so that once validated and stored the form redirects to the url agregar:formulario2 with the pk of the newly created object

  • In view Model2CreateView , to assign the relationship according to what it receives per parameter

  • The Modelo2Form field must be excluded from the form relacionModelo1 , since you store it dynamically in your view

    # forms.py
    
    class Modelo2Form(forms.ModelForm):
        class Meta:
            model = Modelo2
            fields = ['curp', 'nacionalidad']
    
            labels = {
                'curp': 'CURP',
                'nacionalidad': 'Nacionalidad',
            }
    
            widgets = {
                'curp': forms.TextInput(),
                'nacionalidad': forms.TextInput(),
            }
    
    # views.py
    
    from django.http import HttpResponseRedirect
    from django.shortcuts import get_object_or_404
    
    class Model1CreateView(CreateView):
        model = Modelo1
        form_class = Modelo1Form
        template_name = 'form.html'
        success_url = None
    
        #no se como pasarle la pk a la siguiente página
        def form_valid(self, form):
            instance_model1 = form.save(commit=False)
            # other field to save
            instance_model1.save()
    
            # ya que no tendras un id si no hasta que crees la instancia de modelo1,
            # debes redireccionar con el metodo 'HttpResponseRedirect' y generando la url con el metodo 'reverse'
            return HttpResponseRedirect(reverse('agregar:formulario2', kwargs={'pk': instance_model1.pk}))
    
    
    class Model2CreateView(CreateView):
        model = Modelo2
        form_class = Modelo2Form
        template_name = 'form.html'
        success_url = reverse_lazy('agregar:formulario1')
    
        #no se como asiganrle la pk del formulario1 al campo relacionModelo1
        def form_valid(self, form):
            # creas una instancia, sin salvar, de la clase Modelo2
            instance_model2 = form.save(commit=False)
    
            # utilizas la instancia de 'Modelo1' creada en el metodo post para asiganarle a tu instancia de 'Modelo2'
            # esta instancia se crea ya que al 'enviar' el formulario, esta sera la accion http que obedece el view
            instance_model2.relacionModelo1 = self.instance_model1
            instance_model2.save()
    
            # no necesitas un redirect, ya que tomara por defecto la url definida en el parametro 'success_url'
            return super(Model2CreateView, self).form_valid(form)
    
        def get(self, request, *args, **kwargs):
            self.instance_model1 = get_object_or_404('Modelo1', pk=kwargs.get('pk'))
            return super(Model2CreateView, self).get(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            self.instance_model1 = get_object_or_404('Modelo1', pk=kwargs.get('pk'))
            return super(Model2CreateView, self).post(request, *args, **kwargs)
    
  • answered by 07.03.2018 / 05:10
    source