2017-01-22 162 views
0

我有一個模型,該模型從一個表中一個數據庫中檢索數據,以及檢索其他兩個表數據另外兩個模型(StreetsCities)。所有這些信息都需要從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,如果vehicleLandVehicle的實例只是一個空變量。

我明白,我需要解析的數據,一旦我能找回它,但現在它似乎並沒有被檢索任何東西(不能爲它打印出來東西要麼)。

編輯/更新:

通過添加self參數,每個屬性(上述改變),我收到一個錯誤:

Cannot resolve keyword 'streets' into field. Choices are: id, lat, lon, name 

至少我得到了一些錯誤,現在,但我仍然不確定如何訪問屬性。

+0

通過空的變量,你的意思是'None'?嘗試在那裏放置一些'print'來查看代碼是否被執行。此外,代碼看起來很奇怪 - 你的方法在任何地方都缺少「self」(作爲第一個參數)。 – yedpodtrzitko

+0

@yedpodtrzitko如果我嘗試在屬性中打印文本到控制檯(例如在「streets()'屬性中打印」Test「),它會起作用,所以它似乎被執行,但如果我在屬性到一個變量和打印,沒有什麼打印到控制檯。我已將缺少的'self'參數添加到每個屬性中,並更新了有關該錯誤的更多信息。 – swiftsly

回答

1

當然啊,我現在看到了。錯誤表示它 - 您試圖在filter()表達式中使用streets作爲列,但它不是任何地方定義的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將它轉換爲查詢。因此,當您想通過街道名稱篩選數據庫記錄時,必須在數據庫中包含street列,以便數據庫可以在數據上進行比較。

例如該位:Q(street__name__contains='foobar')被轉換爲SQL查詢等select * from vehicle where street LIKE '%foobar%'。所以很顯然,預計列street需要在那裏。不僅用於過濾數據,還需要存儲這些數據。

如果你不理解Django的ORM是如何工作的,請閱讀文檔的這一部分:https://docs.djangoproject.com/en/1.10/topics/db/queries/

+0

它開始有意義,但是我必須完全搞不清楚LandVehicle.objects.filter(Q(cities__name__contains = self.name))在做什麼。正如你指出的那樣,街道不是一個專欄,但最終目標是對於「街道」來說,表格列(包含所有列數據)可以解析爲一個元組,所以爲了澄清,我應該創建一個自定義字段,它將充當所有行數據? – swiftsly