我有一个模型从数据库中的一个表中检索数据,另外两个模型(Cities
和LandVehicle
)从另外两个表中检索数据。所有这些信息都需要从LandVehicle
模型中访问。我在确定如何从其他表中检索数据到class Vehicle(models.Model):
name = models.CharField(max_length=500)
lat = models.DecimalField(max_digits=15,decimal_places=6)
lon = models.DecimalField(max_digits=15,decimal_places=6)
radius = Decimal(.06)
@abstractproperty
def streets(self):
pass
@abstractproperty
def cities(self):
pass
@cached_property
def nearby_vehicles(self):
return Vehicle.objects.filter(lat__range=[self.lat - 2, self.lat + 2], lon__range=[self.lon - 2, self.lon + 2])
# Meta
class Meta:
abstract = True
class LandVehicle(Vehicle):
@property
def streets(self):
name_substr = self.name
if " " in name_substr:
name_substr = name_substr[:name_substr.index(" ")]
return LandVehicle.objects.filter(Q(streets__name__contains=self.name) |
Q(streets__name__contains=name_substr) |
(Q(streets__lat__range=[self.lat - self.radius, self.lat + self.radius]) &
Q(streets__lon__range=[self.lon - self.radius, self.lon + self.radius])))
@property
def cities(self):
name_substr = self.name
if " " in name_substr:
name_substr = name_substr[:name_substr.index(" ")]
return LandVehicle.objects.filter(Q(cities__name__contains=self.name) |
Q(cities__name__contains=airport_name_substr) |
(Q(cities__lat__range=[self.lat - self.radius, self.lat + self.radius]) &
Q(cities__lon__range=[self.lon - self.radius, self.lon + self.radius])))
# Meta
class Meta:
db_table = 'landvehicles'
class Streets(models.Model):
# Meta
class Meta:
db_table = 'streets'
class Cities(models.Model):
# Meta
class Meta:
db_table = 'cities'
模型中的属性时遇到了一些麻烦。以下是我正在使用的课程结构:
vehicle.streets
我不一定从现在设置的方式中收到错误,但访问视图中的数据,例如vehicle
,如果LandVehicle
是一个实例self
只是一个空变量。
我知道我需要在检索数据后解析数据,但是现在它似乎没有检索任何内容(也不能为它打印任何内容)。
修改/更新
通过将Cannot resolve keyword 'streets' into field. Choices are: id, lat, lon, name
参数添加到每个属性(上面已更改),我收到错误:
1.8.6 :090 > txt = open("ex15_sample.txt")
=> #<File:ex15_sample.txt>
1.8.6 :091 > puts txt.read
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
=> nil
1.8.6 :092 >
至少我现在遇到了一些错误,但我仍然不确定如何访问这些属性。
答案 0 :(得分:1)
啊,当然,现在我看到了。错误说明了 - 您尝试在streets
表达式中使用filter()
作为列,但它不是在任何位置定义的db列。您需要将列定义为Field
类的祖先(+为其进行迁移),然后您可以在数据库查询中使用它。
如果将以这种方式调用db列,您还必须将属性streets
重命名为其他内容。
编辑下面的评论:你可以拥有这两个东西,但它们显然不能有相同的名称。例如,这样:
class Vehicle(models.Model):
# ...
# a singular name
street = models.CharField(max_length=128)
@property
def streets(self): # plural
# you can use this instead of the 3 lines with `if` you have now
name_substr = self.name.split()[0]
#since the column is singular `street`, is needs to be singular in the query below too.
return LandVehicle.objects.filter(Q(street__name__contains=self.name) |
Q(street__name__contains=name_substr) |
(Q(street__lat__range=[self.lat - self.radius, self.lat + self.radius]) &
Q(street__lon__range=[self.lon - self.radius, self.lon + self.radius])))
至于你的问题LandVehicle.objects.filter()
做了什么,它是一种编写SQL查询而不实际编写原始SQL查询的方便方法。 Django然后将它转换为您的查询。因此,当您想通过街道名称过滤db记录时,您必须在数据库中包含street
列,因此数据库可以在数据上方进行比较。
例如,这一位:Q(street__name__contains='foobar')
被转换为像select * from vehicle where street LIKE '%foobar%'
这样的SQL查询。显然,预期列street
需要存在。不仅用于过滤数据,还需要存储这些数据。
如果您不了解Django ORM的工作原理,请阅读文档的这一部分:https://docs.djangoproject.com/en/1.10/topics/db/queries/