2017-01-22 5 views
0

私はデータベース内のあるテーブルからデータを取得するモデルと、2つの他のテーブルからデータを取得する2つの他のモデル(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がある場合、私は必ずしも、そのようvehicle.streetsとして、それは今でセットアップされた道からのエラーを取得しますが、ビュー内のデータにアクセスしないでくださいLandVehicleのインスタンスは、空の変数に過ぎません。

データを取得できたら解析する必要があると思いますが、今は何も取得していないようです(どちらも印刷できません)。

編集/更新:少なくとも私は今、エラーのいくつかの並べ替えを取得

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

(上記の変更)の各プロパティにselfパラメータを追加することにより、私はエラーが表示されますしかし、私はまだプロパティにアクセスする方法がわかりません。

+0

空の変数によって、あなたは 'NONE'を意味ですか?コードが実行されたかどうかを確認するために 'print'sをいくつか入れてみてください。また、コードが奇妙に見えます - あなたのメソッドにはどこでも 'self'が(最初のパラメータとして)欠けています。 – yedpodtrzitko

+0

@yedpodtrzitkoプロパティの中でコンソールにテキストを印刷しようとすると( 'streets()'プロパティの "Test"のように)、動作しているように見えますが、プロパティを変数に追加し、それを印刷します。何もコンソールには何も表示されません。私は不足している 'self'パラメータを各プロパティに追加し、エラーの詳細をいくつか追加して投稿を更新しました。 – swiftsly

答えて

1

もちろん、今私はそれを見ます。エラーは、filter()式の中でstreetsを列として使用しようとしていますが、どこにでも定義されているdb列ではありません。列をFieldクラスの祖先として定義する必要があります(+これをマイグレーションしてください)。そして、それをdbクエリで使用することができます。

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/

+0

それは意味をなさないようになっていますが、 'LandVehicle.objects.filter(Q(cities__name__contains = self.name)'が何をしているのか完全に混乱していなければなりません。 'streets'がテーブル行のリストを保持して(それらの列データすべてを)タプルに変換できるようにするために、私はカスタムフィールドを作成して、行データ? – swiftsly

関連する問題