4

関連するエンティティを表示するコンボでフォームをレンダリングしようとしています。したがって、ModelChoiceField を使用しています。

表示するエンティティを制限する必要があるまでは、このアプローチはうまく機能します。単純なクエリ式を使用しても問題なく動作しますが、生の SQL クエリを使用すると問題が発生します。

したがって、動作する私のコードは、クエリセットをフィルター式に設定します。

class ReservationForm(forms.Form):
    location_time_slot = ModelChoiceField(queryset=LocationTimeSlot.objects.all(), empty_label="Select your prefered time")

def __init__(self,*args,**kwargs):
    city_id = kwargs.pop("city_id")     # client is the parameter passed from views.py
    super(ReservationForm, self).__init__(*args,**kwargs)

    # TODO: move this to a manager        
    self.fields['location_time_slot'].queryset = LocationTimeSlot.objects.filter(city__id = city_id )

しかし、それを生のクエリに変更すると、問題が発生し始めます。動作しないコード:

class ReservationForm(forms.Form):
        location_time_slot = ModelChoiceField(queryset=LocationTimeSlot.objects.all(), empty_label="Select your prefered time")

    def __init__(self,*args,**kwargs):
        city_id = kwargs.pop("city_id")     # client is the parameter passed from views.py
        super(ReservationForm, self).__init__(*args,**kwargs)

        # TODO: move this to a manager        
        query = """SELECT ts.id, ts.datetime_to, ts.datetime_from, ts.available_reserves, l.name, l.'order' 
    FROM  reservations_locationtimeslot AS ts
     INNER JOIN reservations_location AS l ON l.id = ts.location_id 
     WHERE l.city_id = %s     
     AND ts.available_reserves > 0  
     AND ts.datetime_from > datetime() """

    time_slots = LocationTimeSlot.objects.raw(query, [city_id])

    self.fields['location_time_slot'].queryset = time_slots

ウィジェットをレンダリングしようとしたときに発生する最初のエラーは次のとおりです。「RawQuerySet」オブジェクトには属性「all」がありません

enter link description hereのcommetsの1つのおかげで、次のようにして解決できました。

 time_slots.all = time_slots.__iter__ # Dummy fix to allow default form rendering with raw SQL

しかし、フォームを投稿すると、「RawQuerySet」オブジェクトに属性「get」がありません。

ModelChoiceField で使用する RawQuerySet を準備する適切な方法はありますか?

ありがとう!

4

2 に答える 2

1

不足しているメソッドを追加する問題を一時的に修正しました。私が現在 ModelChoiceField を使用している方法では、all() メソッドと get() メソッドを追加するだけで済みましたが、別のシナリオでは、他のメソッドも追加する必要がある場合があります。また、これは完全な解決策ではありません。1) get メソッドをこのように定義すると、誤った結果が生じる可能性があります。get() メソッドは、選択したオプションが all() によって返されるオプション内にあることを検証するために使用されると思います。私が一時的に実装した方法は、IDがテーブルに存在することを検証するだけです。2) get メソッドは、このように指定するとパフォーマンスが低下すると思います。

誰かがより良い解決策を考えることができる場合は、私に知らせてください。

だから私の一時的な解決策:

class LocationTimeSlotManager(models.Manager):
    def availableSlots(self, city_id):
        query = """SELECT ts.id, ts.datetime_to, ts.datetime_from, ts.available_reserves, l.name, l.'order' 
            FROM  reservations_locationtimeslot AS ts
            ..... 
            ..... 
            MORE SQL """ 

        time_slots = LocationTimeSlot.objects.raw(query, [city_id])

        # Dummy fix to allow default form rendering with raw SQL
        time_slots.all = time_slots.__iter__ 
        time_slots.get = LocationTimeSlot.objects.get

        return time_slots
于 2013-07-01T20:31:21.270 に答える
1

そこに実際に生のクエリが必要ですか?そのクエリを見るだけで、 でそれを実行できない理由がわかりませんfilter(location__city=city_id, available_reserves__gte=0, datetime_from__gt=datetime.datetime.now())

生のクエリ セットには、従来のクエリ セットで定義されている多くのメソッドが欠けているため、これらすべてのメソッドに対して独自の定義を作成しない限り、それらを適切な場所にドロップしても機能しない可能性があります。

于 2013-06-26T22:40:35.247 に答える