How can I use Form Wizard in Model Forms with django?

0

I want in the same template to capture 3 different forms through a step by step (steps). I did it initially with dividing the forms to capture, but I keep losing info of the first, or second step ... I was looking at something from Form Wizard in the doc, but it is not clear to me to do it with Model Forms ... the idea is the info I update it to the BD at the end, or the same, can be in each step ...

I have 2 separate models in 3 different forms to capture the info ...

if someone can give me an idea .... Thanks

Here I leave part of the code ... including the previous version ...

/ profile is the stick ... / test is the one I want to implement ...

models.py

    from django.db import models

    from django.contrib.auth.models import User
    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from pinax.stripe.models import Customer
    from imagekit.models import ProcessedImageField
    from imagekit.processors import ResizeToFill
    import hashlib
    import uuid
    import datetime

    from cities.models import *

    class Profile(models.Model):

        user = models.OneToOneField(User, on_delete=models.CASCADE)
        bio = models.TextField(max_length=500, blank=True)
        birth_date = models.DateField(null=True, blank=True)
        GENDER_CHOICES = (('M', 'Male'), ('F', 'Female'))
        gender = models.CharField(max_length=1, choices=GENDER_CHOICES, null=True)
        initial_name = models.CharField(max_length=2, null=True, blank=True)
        url = models.URLField(null=True)
        company = models.CharField(max_length=50, null=True, blank=True)
        phone = models.CharField(max_length=15, null=True, unique=True)
        job = models.CharField(max_length=50, null=True, blank=True)
        position = models.CharField(max_length=50, null=True, blank=True)
        address = models.CharField(max_length=1000, null=True, blank=True)
        address2 = models.CharField(max_length=1000, null=True, blank=True)
        city = models.ForeignKey(City, null=True, blank=True, on_delete=models.SET_NULL)
        state = models.ForeignKey(Region, null=True, blank=True, on_delete=models.SET_NULL)
        country = models.ForeignKey(Country, null=True, blank=True, on_delete=models.SET_NULL)
        postal_code = models.CharField(max_length=10, null=True, blank=True)

    def __str__(self):
        return self.user.username

    class Meta:
        app_label = 'app'

    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            Profile.objects.create(user=instance)

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.profile.save()

forms.py

    from django import forms
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    from django.contrib.auth.models import User

    from .models import Profile
    from cities.models import Region, City

    class UserForm(forms.ModelForm):
        class Meta:
            model = User

            fields = [
                'first_name',
                'last_name',
                'email',
            ]

            labels = {
                'first_name': 'First Name',
                'last_name': 'Last Name',
                'email': 'Email',
            }

            widgets = {
                'first_name': forms.TextInput(attrs={'class': 'form-control'}),
                'last_name': forms.TextInput(attrs={'class': 'form-control'}),
                'email': forms.TextInput(attrs={'class': 'form-control'}),
            }

    class ProfileForm(forms.ModelForm):
        class Meta:
            model = Profile
            fields = [
                'initial_name',
                'gender',
                'birth_date',
                'phone',
                'job',
                'position',
                'company',

           ]

           labels = {
               'initial_name': 'Initials Name',
               'gender': 'Gender',
               'birth_date': 'Birth Date',
               'phone': 'Phone',
               'job': 'Job',
               'position': 'Position',
               'company': 'Company',
           }

           widgets = {
               'initial_name':forms.TextInput(attrs={'class': 'form-control'}),
               'gender': forms.Select(choices=(('S', 'Select'), ('M', 'Male'), ('F', 'Female'))),
               'birth_date': forms.DateInput(attrs={'class': 'datepicker', 'placeholder': 'yyyy-mm-dd'}),
               'phone': forms.TextInput(attrs={'class': 'form-control'}),
               'job': forms.TextInput(attrs={'class': 'form-control'}),
               'position': forms.TextInput(attrs={'class': 'form-control'}),
               'company': forms.TextInput(attrs={'class': 'form-control'}),
          }

    class AddressForm(forms.ModelForm):
        class Meta:
            model = Profile
            fields = [
                'country',
                'state',
                'city',
                'address',
                'address2',
                'postal_code',

           ]

           labels = {
               'country': 'Country',
               'state': 'State',
               'city': 'City',
               'address': 'Postal Address',
               'address2': 'Postal Address 2',
               'postal_code': 'Postal Code',
           }

           widgets = {
               'country': forms.Select(attrs={'class': 'form-control'}),
               'state': forms.Select(attrs={'class': 'form-control'}),
               'city': forms.Select(attrs={'class': 'form-control'}),
               'address': forms.TextInput(attrs={'class': 'form-control'}),
               'address2': forms.TextInput(attrs={'class': 'form-control'}),
               'postal_code': forms.TextInput(attrs={'class': 'form-control'}),
    }

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            #self.fields['state'].queryset = Region.objects.none()
            self.fields['city'].queryset = City.objects.none()

            if 'country' in self.data:
                try:
                    country_id = int(self.data.get('country'))
                    self.fields['state'].queryset = Region.objects.filter(country_id=country_id).order_by('name')
                except (ValueError, TypeError):
                    pass
            if 'state' in self.data:
                try:
                    region_id = int(self.data.get('state'))
                    self.fields['city'].queryset = City.objects.filter(region_id=region_id).order_by('name')
                 except (ValueError, TypeError):
                    pass

views.py

    @login_required
    @transaction.atomic
    def update_profile(request):
        if request.method == 'POST':
            userform = UserForm(request.POST, instance=request.user)
            profileform = ProfileForm(request.POST, instance=request.user.profile)
            addressform = AddressForm(request.POST, instance=request.user.profile)
            if userform.is_valid() and profileform.is_valid():
                userform.save()
                profileform.save()
                messages.success(request, ('Your profile was successfully updated!'))
            else:
                messages.error(request, ('Please correct the error below.'))
            if addressform.is_valid():
               addressform.save()
               return redirect('profile')
        else:
            userform = UserForm(instance=request.user)
            profileform = ProfileForm(instance=request.user.profile)
            addressform = AddressForm(instance=request.user.profile)
            return render(request, 'app/panel_forms.html', {
                'userform': userform,
                'profileform': profileform,
                'addressform': addressform
            })

    def load_cities(request):
        region_id = request.GET.get('state')
        cities = City.objects.filter(region_id=region_id).order_by('name')
        return render(request, 'app/city_dropdown_list_options.html', {'cities': cities})

    def load_states(request):
       country_id = request.GET.get('country')
       states = Region.objects.filter(country_id=country_id).order_by('name')
       return render(request, 'app/state_dropdown_list_options.html', {'states': states})

    FORMS = [("userform", UserForm),
        ("profileform", ProfileForm),
        ("addressform", AddressForm)]

    TEMPLATES = {"userform": "app/test.html",
        "profileform": "app/test.html",
        "addressform": "app/test.html"}

    class ProfileWizard(SessionWizardView):
        def get_template_names(self):
            return [TEMPLATES[self.steps.current]]

        def done(self, form_list, **kwargs):
            return render(self.request, 'app/index.html', {
            'form_data': [form.cleaned_data for form in form_list],
        })

urls.py

    from django.urls import path
    from django.conf.urls import url

    from django.contrib.auth import views as auth_views
    from . import views
    from .forms import UserForm, ProfileForm, AddressForm
    from .views import ProfileWizard, FORMS

    urlpatterns = [
        path('profile', views.update_profile, name='profile'),
        path('ajax/load-states/', views.load_states, name='ajax_load_states'),
        path('ajax/load-cities/', views.load_cities, name='ajax_load_cities'),
        path('test', ProfileWizard.as_view( FORMS )),
    ]
    
asked by José Ramón Quintero García 15.06.2018 в 16:31
source

0 answers