I am trying to make migrations for my models:
from django.db import models
TAKEN = (
(True, 'Yes'),
(False, 'No')
)
class Room(models.Model):
name = models.CharField(max_length=32)
number = models.IntegerField()
taken = models.BooleanField(choices=TAKEN)
description = models.CharField(max_length=128)
ROOMS_CHOICE = (Room.objects.filter(taken=False))
class Reservation(models.Model):
date = models.DateField()
hours = models.IntegerField()
choice = models.OneToOneField(Room, on_delete=models.CASCADE, choices=ROOMS_CHOICE)
forms for the models:
from django import forms
from .models import TAKEN, ROOMS_CHOICE
class NewRoomForm(forms.Form):
name = forms.CharField(label='Name', max_length=32)
number = forms.IntegerField(label='Room Number')
taken = forms.ChoiceField(choices=TAKEN, label='Taken', widget=forms.Select)
description = forms.CharField(label='Description', widget=forms.Textarea)
class ReservationForm(forms.Form):
date = forms.DateField(label='Date', widget=forms.SelectDateWidget)
hours = forms.IntegerField(label='hours', max_value=8)
choice = forms.ChoiceField(choices=ROOMS_CHOICE, label='room', widget=forms.Select)
When I try to make migrations, an ProgrammingError appears:
django.db.utils.ProgrammingError: (1146, "Table 'conference_room.conference_room' doesn't exist")
I try to make a view where user can book a conference room from a available rooms (those that are not occupied - taken=False). I assume I made some mistakes during building OneToOne relation and writing choices based on the Room model, and that is why the error appeared. How can I rewrite my models and forms?
There are indeed a number of problems here.
The thing causing your issue is not actually your OneToOneField, but the fact that in the definition of ROOMS_CHOICE you are doing a query at module level - so it will be executed when the models file is first imported, before the migration has a chance to run. That sort of thing needs to be done in a method, in this case probably the __init__
of the form (if you need it at all, which you don't - see below).
However there are several more issues. Firstly, you should not be using OneToOne; that implies that a room can only have one reservation, which obviously isn't the case. You need a ForeignKey, which is a one-to-many relation.
Then, you shouldn't use a ChoiceField here. Django includes a field for getting choices from a model: it's called ModelChoiceField, and it takes a queryset:
choice = forms.ModelChoiceField(queryset=Room.objects.filter(taken=False), label='room', widget=forms.Select)
so you in fact don't need to define ROOMS_CHOICE at all.
(I'd also point out that having a taken
field on Room doesn't make sense either; a room is only taken at a certain time. You actually need to query for rooms that are not booked at the date/time the reservation is for, which you can't do until the user has actually chosen that date.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.