模型属性返回空

时间:2017-01-22 22:01:43

标签: python django django-models

我有一个模型从数据库中的一个表中检索数据,另外两个模型(CitiesLandVehicle)从另外两个表中检索数据。所有这些信息都需要从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 > 

至少我现在遇到了一些错误,但我仍然不确定如何访问这些属性。

1 个答案:

答案 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/