ATISE
ATISE

Reputation: 34

how to put multiple Forms in the same views.py function - Django

I need to put four Form in one views.py function, but I have no idea how to do it.

I need every form to show on the site on the same time.

I will take any advice on how I can solve this problem.

models.py

# Hotel
class Hotel(models.Model):
    customer = models.ForeignKey(Account, null=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    short_description = models.TextField(max_length=250)
    long_description = models.TextField(max_length=2000, null=True)
    HOTEL_STAR = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
        ('5', '5')
    )
    star = models.TextField(max_length=1, default=5, choices=HOTEL_STAR, null=True)
    picture = models.ImageField(upload_to='images/%Y/%m/%d/',default="images/default.jpg" , blank=True)
    created = models.DateTimeField(auto_now_add=True, null=True)


    def __str__(self):
        return str(self.name)

# Room
class Room(models.Model):
    hotel = models.ForeignKey(Hotel, null=True, on_delete=models.CASCADE)
    def __str__(self):
        return f'Room of {self.hotel}'

# Single type for Room
class Single(models.Model):
    room = models.ForeignKey(Room, null=True, on_delete=models.CASCADE)

    ROOM_NAME = (
        ('Budget_single_room', 'Budget Single Room'),
        ('Standard_single_room', 'Standard Single Room'),
        ('Superior_single_room', 'Superior Single Room'),
        ('Deluxe_single_room', 'Deluxe Single Room'),
    )
    name = models.TextField(max_length=30, choices=ROOM_NAME, null=True)

    ROOM_SMOKE = (
        ('Smoking', 'Smoking'),
        ('Non-Smoking', 'Non-Smoking'),
    )
    smoke = models.TextField(max_length=15, choices=ROOM_SMOKE, null=True)

    bed = models.IntegerField()
    capacity = models.IntegerField()
    room_size = models.IntegerField()

    def __str__(self):
        return f'{self.name}'

# Double type for Room
class Double(models.Model):
    room = models.ForeignKey(Room, null=True, on_delete=models.CASCADE)

    ROOM_NAME = (
        ('Budget_Double_room', 'Budget Double Room'),
        ('Standard_Double_room', 'Standard Double Room'),
        ('Superior_Double_room', 'Superior Double Room'),
        ('Deluxe_Double_room', 'Deluxe Double Room'),
    )
    name = models.TextField(max_length=30, choices=ROOM_NAME, null=True)

    ROOM_SMOKE = (
        ('Smoking', 'Smoking'),
        ('Non-Smoking', 'Non-Smoking'),
    )
    smoke = models.TextField(max_length=15, choices=ROOM_SMOKE, null=True)

    bed = models.IntegerField()
    capacity = models.IntegerField()

    BED_SIZE = (
        ('Single_bed_90_130', 'Single Bed / 90-130 cm wide'),
        ('Double_bed_131_150', 'Double Bed / 131-150 cm wide'),
        ('Large_bed_king_size_151_180', 'Large Bed (King Size) / 151-180 cm wide'),        
        )

    room_size = models.IntegerField()


    def __str__(self):
        return f'{self.name}'

# Bed Quantity for Single and Double types
class BedQuantity(models.Model):
    type = models.ForeignKey(Double, null=True, on_delete=models.CASCADE)

    number_of_bed = models.IntegerField(null=True)
    def __str__(self):
        return f'{self.type} with {self.number_of_bed} beds'

forms.py

from django.forms import ModelForm
from .models import Hotel, Apartment, Single, Double, BedQuantity

class HotelForm(ModelForm):
    class Meta:
        model = Hotel
        exclude = ('customer',)

class SingleForm(ModelForm):
    class Meta:
        model = Single
        exclude = ('room',)


class DoubleForm(ModelForm):
    class Meta:
        model = Double
        exclude = ('room',)


class BedQuantityForm(ModelForm):
    class Meta:
        model = BedQuantity
        exclude = ('type',)


class ApartmentForm(ModelForm):
    class Meta:
        model = Apartment
        exclude = ('customer',)

views.py

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Hotel, Room, Single, Double, BedQuantity
from .forms import HotelForm, ApartmentForm, SingleForm, DoubleForm, BedQuantityForm

@login_required
def add_hotel(request):
    form = HotelForm()
    if request.method == "POST":
        form = HotelForm(request.POST, request.FILES)
        if form.is_valid():
            data = form.save(commit=False)
            data.customer = request.user
            data.save()
            return redirect('/')

    context = {'form':form,}
    return render(request, 'add_hotel.html', context)

Upvotes: 0

Views: 232

Answers (1)

Abhyudai
Abhyudai

Reputation: 934

In case you want to render more than one form from a view you will have to instantiate all of them in your view first and then pass them to the template.

Something along these lines should work.

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Hotel, Room, Single, Double, BedQuantity
from .forms import HotelForm, ApartmentForm, SingleForm, DoubleForm, BedQuantityForm

@login_required
def add_hotel(request):
    # instantiate the forms
    hotel_form = HotelForm()
    apartment_form = ApartMentForm()
    single_form = SingleForm()
    double_form = DoubleForm()

    if request.method == "POST":
        hotel_form = HotelForm(request.POST, request.FILES)
        apartment_form = ApartMentForm(request.POST)
        single_form = SingleForm(request.POST)
        double_form = DoubleForm(request.POST)
        if form.is_valid():
            data = hotel_form.save(commit=False)
            data.customer = request.user
            data.save()
            # do your thing with other forms and save them as well
            return redirect('/')

    context = {
        'hotel_form': hotel_form,
        'apartment_form': apartment_form,
        ...
     }
    return render(request, 'add_hotel.html', context)

Also as a separate piece of advice, please try to avoid using python keywords such a type for variable names.

Upvotes: 2

Related Questions