django 我有两个模型Flight和Airport,Airport通过外键与Flight相关,但是在将Flights添加到DB时,我得到了值错误

qgelzfjb  于 2023-01-10  发布在  Go
关注(0)|答案(1)|浏览(106)
from django.db import models

# Create your models here.

class Airport(models.Model):
    code = models.CharField(max_length=64)
    city = models.CharField(max_length=64)

    def __str__(self):
        return f"{self.id}:{self.city} ({self.code})"

class Flight(models.Model):
    origin = models.ForeignKey(Airport,on_delete=models.CASCADE,related_name="departures")
    destination = models.ForeignKey(Airport,on_delete=models.CASCADE,related_name="arrivals")
    duration = models.IntegerField()

    def __str__(self):
        return f"{self.id}: {self.origin} to {self.destination}"

class Passenger(models.Model):
    first = models.CharField(max_length=64)
    last = models.CharField(max_length=64)
    flights = models.ManyToManyField(Flight, blank = True,related_name="passengers")

    def __str__(self):
        return f"{self.first} {self.last}"

当我查询机场中的对象时,我的机场列表中有纽约和伦敦。但当我想添加它们之间的航班时,我无法做到这一点。它说在机场中没有名为纽约的示例。我也尝试了其他机场,但得到了相同的错误

type In [5]: from flights.models import *

In [6]: Airport.objects.all()
Out[6]: <QuerySet [<Airport: 1:New York (JFK)>, <Airport: 2:London (LHR)>, <Airport: 3:Paris (CDG)>, <Airport: 4:Tokyo (NRT)>, <Airport: 5:Shanghai (PVG)>, <Airport: 6:Istanbul (IST)>, <Airport: 7:Moscow (Svo)>, <Airport: 8:Lima (LIM)>]>

In [7]: f  = Flight(origin = "New York"  ,destination = "London" , duration = 818)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[7], line 1
----> 1 f  = Flight(origin = "New York"  ,destination = "London" , duration = 818)

File /opt/homebrew/lib/python3.10/site-packages/django/db/models/base.py:541, in Model.__init__(self, *args, **kwargs)
    535 if is_related_object:
    536     # If we are passed a related instance, set it using the
    537     # field.name instead of field.attname (e.g. "user" instead of
    538     # "user_id") so that the object gets properly cached (and type
    539     # checked) by the RelatedObjectDescriptor.
    540     if rel_obj is not _DEFERRED:
--> 541         _setattr(self, field.name, rel_obj)
    542 else:
    543     if val is not _DEFERRED:

File /opt/homebrew/lib/python3.10/site-packages/django/db/models/fields/related_descriptors.py:235, in ForwardManyToOneDescriptor.__set__(self, instance, value)
    231 # An object must be an instance of the related class.
    232 if value is not None and not isinstance(
    233     value, self.field.remote_field.model._meta.concrete_model
    234 ):
--> 235     raise ValueError(
    236         'Cannot assign "%r": "%s.%s" must be a "%s" instance.'
    237         % (
    238             value,
    239             instance._meta.object_name,
    240             self.field.name,
    241             self.field.remote_field.model._meta.object_name,
    242         )
    243     )
    244 elif value is not None:
    245     if instance._state.db is None:

ValueError: Cannot assign "'New York'": "Flight.origin" must be a "Airport" instance.here

有人能帮我弄明白这是怎么回事吗

hmae6n7t

hmae6n7t1#

您可以将code设置为唯一字段,甚至是主键,并将其用作引用:

class Airport(models.Model):
    code = models.CharField(max_length=64, unique=True)
    city = models.CharField(max_length=64)
    destiniations = models.ManyToManyField(
        'self',
        through='Flight',
        through_fields=('origin', 'destination'),
        related_name='origins',
    )

    def __str__(self):
        return f'{self.id}:{self.city} ({self.code})'

class Flight(models.Model):
    origin = models.ForeignKey(
        Airport,
        to_field='code',
        on_delete=models.CASCADE,
        related_name='departures',
    )
    destination = models.ForeignKey(
        Airport,
        to_field='code',
        on_delete=models.CASCADE,
        related_name='arrivals',
    )
    duration = models.DurationField()

    def __str__(self):
        return f'{self.id}: {self.origin_id} to {self.destination_id}'

然后,您可以使用以下选项创建航班:

from datetime import timedelta

f = Flight(
    origin_id='JFK', destination_id='LHR', duration=timedelta(hours=8, minutes=18)
)

相关问题