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 )),
]