简体   繁体   English

Django的。 如何从其他模型中进行模型选择

[英]Django. How to make model choices from another model

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: 当我尝试进行迁移时,出现ProgrammingError:

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. 我假设在建立OneToOne关系和基于Room模型编写选择项时犯了一些错误,这就是为什么会出现错误。 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. 引起问题的原因实际上不是您的OneToOneField,而是在ROOMS_CHOICE的定义中您正在模块级别进行查询的事实-因此它将在首次导入模型文件时执行,并且有机会运行迁移。 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). 这类事情需要用一种方法来完成,在这种情况下,可能是表单的__init__ (如果根本不需要,则不需要-见下文)。

However there are several more issues. 但是,还有更多问题。 Firstly, you should not be using OneToOne; 首先,您不应该使用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. 您需要一个ForeignKey,这是一对多关系。

Then, you shouldn't use a ChoiceField here. 然后,您不应在此处使用ChoiceField。 Django includes a field for getting choices from a model: it's called ModelChoiceField, and it takes a queryset: Django包含一个用于从模型中获取选择的字段:它称为ModelChoiceField,并带有一个查询集:

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. 因此,实际上您根本不需要定义ROOMS_CHOICE。

(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.) (我还要指出,在“房间”上使用“ taken字段也没有意义;房间仅在特定时间使用。实际上,您需要查询在预订日期/时间未预订的房间为此,您必须在用户实际选择该日期后才能执行此操作。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM