简体   繁体   English

如何从Django中的models.py查询数据库项目?

[英]How to query database items from models.py in Django?

I have different model. 我有不同的型号。 Choices of Multiselctfield of one model is dependent on another model.So , database has to be queried inside model.py While doing so, this causes problem in migration. 一个模型的Multiselctfield的选择取决于另一个模型。因此,必须在model.py中查询数据库,这会导致迁移问题。 (Table doesn't exist error) (表不存在错误)

class Invigilator(models.Model):
    ---

# this method queries Shift objects and Examroom
def get_invigilator_assignment_list ():
    assignment = []
    shifts = Shift.objects.all()
    for shift in shifts:
        rooms= ExamRoom.objects.all()
        for room in rooms:
            assign = str (shift.shiftName)+ " " +str (room.name) 
            assignment.append (assign)
    return assignment
assignment_choice = []
assign = get_invigilator_assignment_list()
i = 0
for assignm in assign:
    datatuple = (i,assignm)
    assignment_choice.append(datatuple) 
    i= i+1
ASSIGNMENT_CHOICE = tuple(assignment_choice) 

assignment =MultiSelectField (choices = ASSIGNMENT_CHOICE, blank = True, verbose_name="Assignments")

You cannot add dynamic choices because they are all stored in the migration files and table info. 您无法添加动态选择,因为它们都存储在迁移文件和表信息中。 If Django lets you do that, this means that everytime someone adds a record to those 2 models, a new migration should be created and the db should be changed. 如果Django允许您这样做,则意味着每次有人向这2个模型添加一条记录时,都应创建一个新的迁移并更改数据库。 You must approach this problem differently. 您必须以不同的方式处理此问题。

As far as I know django-smart-selects has a ChainedManyToMany field which can do the trick. 据我所知, django-smart- ChainedManyToMany有一个ChainedManyToMany字段可以解决问题。

Here is an example from the repo. 这是仓库中的一个例子。

from smart_selects.db_fields import ChainedManyToManyField

class Publication(models.Model):
    name = models.CharField(max_length=255)

class Writer(models.Model):
    name = models.CharField(max_length=255)
    publications = models.ManyToManyField('Publication', blank=True, null=True)

class Book(models.Model):
    publication = models.ForeignKey(Publication)
    writer = ChainedManyToManyField(
        Writer,
        chained_field="publication",
        chained_model_field="publications")
    name = models.CharField(max_length=255)

This cannot be done in the model and doesn't make sense. 这无法在模型中完成,也没有意义。 It's like you're trying to create a column in a table with a certain fixed set of choices (what is MultiSelecField anyway?), but when someone later adds a new row in the Shift or ExamRoom table, the initial column choices have to change again. 就像您要在具有某些固定选择集的表中创建一列(无论如何是MultiSelecField ?),但是当有人稍后在ShiftExamRoom表中添加新行时,必须更改初始列选择再次。

You can 您可以

  • either make your assignment column a simple CharField and create the choices dynamically when creating the form 将您的assignmentCharField简单的CharField并在创建表单时动态创建选择
  • or you can try to model your relationships differently. 或者您可以尝试以其他方式对您的关系进行建模。 For example, since it looks like assignment is a combination of Shift and ExamRoom , I would create a through relationship: 例如,由于看起来assignmentShiftExamRoom的组合,因此我将创建一个直通关系:
shifts = models.ManyToManyField(Shift, through=Assignment)

class Assignment(Model):
    room = ForeignKey(ExamRoom)
    shift = ForeignKey(Shift)
    invigilator = ForeignKey(Invigilator)

When creating the relationship, you'd have to pick a Shift and a Room which would create the Assignment object. 创建关系时,必须选择一个Shift和一个Room,以创建Assignment对象。 Then you can query things like invigilator.shifts.all() or invigilator.assignment_set.first().room . 然后,您可以查询诸如invigilator.shifts.all()invigilator.assignment_set.first().room

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

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