所以我在开发中的会话中成功存储了一个复杂的对象(非模型)。我已经尝试了每个会话引擎和缓存类型,他们都在开发(Pycharm)。但是,当我将代码移动到生产中时,虽然没有抛出任何错误,但会话会丢失该对象。
以下是我用来设置会话对象的方法:
def instantiate_command_object(request):
try:
ssc = request.session['specimen_search_criteria']
logger.debug('found ssc session variable')
except KeyError:
logger.debug('failed to find ssc session variable')
ssc = SpecimenSearchCommand()
return ssc
然后在一个通过ajax调用异步运行的方法中,我开始对会话中的对象进行更改:
def ajax_add_collection_to_search(request):
ssc = instantiate_command_object(request)
collection_id = request.GET.get('collection')
collection = Collection.objects.get(pk=collection_id)
if collection and collection not in ssc.collections:
ssc.collections.append(collection)
# save change to session
request.session['specimen_search_criteria'] = ssc
# refresh search results
ssc.search()
return render(request, '_search.html')
所有这一切都有效。但是,如果我然后刷新浏览器,则会话丢失。以下是模板的摘录:
{% with criteria=request.session.specimen_search_criteria %}
<div class="search-criteria" id="search-criteria">
<div class="row">
Sesssion:
{{ request.session }}<br/>
Search:
{{ request.session.specimen_search_criteria }}<br/>
Created:
{{ request.session.specimen_search_criteria.key }}<br/>
Collections:
{{ request.session.specimen_search_criteria.collections }}<br/>
同样,在开发中我可以整天刷新并返回相同的对象。在生产中,它将创建一个新对象,或者偶尔会返回先前创建的副本。
一些相关项目:
生产服务器正在运行带有mod_wsgi的Apache httpd。 我已经尝试过memcached,databasecache等行为仍然是一样的。始终在开发中工作,从不在生产中。
我用
尝试过SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
没有。我可以在数据库中看到会话信息,当我取消它时它似乎只是指向内存中复杂对象的位置。
我猜这可能与在多用户环境中运行有关,但同样,我没有使用locmem而且我已经尝试了所有的缓存方法都没有效果。
要清楚,会话本身似乎很好,我可以在其中存储字符串或其他简单项目,它会坚持下去。会话中的复杂对象似乎迷失了。
编辑:我可能还会指出,如果我在返回搜索条件后立即刷新 ,它将实际返回成功。任何超过一秒钟的东西都会消失。
编辑(添加SpecimenSearchCommand的代码):
class SpecimenSearchCommand:
def __init__(self):
pass
created = datetime.datetime.now()
key = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6))
jurisdictions = []
taxa = []
strata = []
collections = []
chrons = []
has_images = False
query = None # The active SQL query, not the actual result records
page_size = 50
current_page = 1
sort_order = 'number'
results = [] # Page of results from paginator
def is_empty(self):
if len(self.jurisdictions) == 0 and len(self.taxa) == 0 and len(self.strata) == 0 and \
len(self.collections) == 0 and len(self.chrons) == 0 and self.has_images is False:
return True
else:
return False
def get_results(self):
paginator = Paginator(self.query, self.page_size)
try:
self.results = paginator.page(self.current_page)
except PageNotAnInteger:
self.results = paginator.page(1)
except TypeError:
return []
except EmptyPage:
self.results = paginator.page(paginator.num_pages)
return self.results
def get_results_json(self):
points = []
for s in self.results:
if s.locality.latitude and s.locality.longitude:
points.append({"type": "Feature",
"geometry": {"type": "Point",
"coordinates": [s.locality.longitude, s.locality.latitude]},
"properties": {"specimen_id": s.id,
"sci_name": s.taxon.scientific_name(),
"cat_num": s.specimen_number(),
"jurisdiction": s.locality.jurisdiction.full_name()}
})
return json.dumps({"type": "FeatureCollection", "features": points})
def search(self):
if self.is_empty():
self.query = None
return
query = Specimen.objects.filter().distinct().order_by(self.sort_order)
if len(self.taxa) > 0:
query = query.filter(taxon__in=get_hierarchical_search_elements(self.taxa))
if len(self.jurisdictions) > 0:
query = query.filter(locality__jurisdiction__in=get_hierarchical_search_elements(self.jurisdictions))
if len(self.strata) > 0:
query = query.filter(stratum__in=get_hierarchical_search_elements(self.strata))
if len(self.chrons) > 0:
query = query.filter(chron__in=get_hierarchical_search_elements(self.chrons))
if len(self.collections) > 0:
query = query.filter(collection__in=get_hierarchical_search_elements(self.collections))
if self.has_images:
query = query.filter(images__isnull=False)
self.query = query
return
def get_hierarchical_search_elements(elements):
search_elements = []
for element in elements:
search_elements = set().union(search_elements, element.get_descendants(True))
return search_elements
答案 0 :(得分:1)
好的,正如Daniel指出的那样,SSC类的属性是类级别而不是实例级别。正确的版本现在看起来像这样:
self.created = datetime.datetime.now()
self.key = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6))
self.jurisdictions = []
self.taxa = []
self.strata = []
self.collections = []
self.chrons = []
self.has_images = False
self.query = None # The active SQL query, not the actual result records
self.page_size = 50
self.current_page = 1
self.sort_order = 'number'
self.results = [] # Page of results from paginator