我试图使用一个组合框展示相关的实体表单,因此我使用了一个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'”。
感谢此处的一位评论者,我解决了这个问题,方法如下:
time_slots.all = time_slots.__iter__ # Dummy fix to allow default form rendering with raw SQL
现在当我提交表单时,出现了类似的问题:
'RawQuerySet'对象没有属性'get'
有没有合适的方法来准备RawQuerySet以便被ModelChoiceField使用?
谢谢!
ModelChoiceField
没有设置使用原始查询集的方法,除非您填写必要的方法。根据您的情况,声明数据库中的视图并创建一个未管理的 Django 模型来表示它可能是有用的。您需要额外的工作将所选视图条目转换回真实的模型实例,但这不应该太难,因为您可以保持 PK 不变。 - Peter DeGlopper