django的新手。我正在尽力使用Django,mongodb和mongoengine实现CRUD。我能够查询数据库并使用数据库中的正确信息呈现我的页面。我还可以使用javascript更改一些文档字段,并使用正确的csrf标记将Ajax POST重新发送回原始的Django View类。
我来回发送的数据有效负载是序列化为json的每个文档模型( VirtualPageModel )的列表(每个元素包含ObjectId字符串以及模型中的其他特定字段。)
这是它开始变得模糊的地方。为了在我的View Class post函数中更新原始文档,我使用对象id进行了一个额外的查询,并循环遍历字典项,每次都设置相应的字段。然后我调用save,任何新数据都正确地推送到Mongo集合。
我不确定我正在做什么来更新现有文档是正确的还是本着django抽象数据库操作的精神。我越深入,我觉得我之前没有使用过某些基础设施(由django或mongoengine提供),因此我不得不在下游进一步做好准备。
我的代码现在的方式我无法创建新文档(虽然这很容易修复)。然而,我真正好奇的是我怎么知道何时删除初始查询中存在的文件,但是被用户/ javascript代码删除了?我是否过度思考我的POST内容应该包含要删除的ObjectId列表(听起来像安全风险,虽然这将是一个内部工具。)
我假设我的View类可能维护它查询的原始文档对象(或简称ObjectIds),我可以从该集合中进行比较,但我似乎无法保持该信息(作为 VolumeSplitterView 中的类变量从开始到我最后收到POST时。
如果有人能查看我的代码,我将不胜感激。看起来似乎Django的“易用性”设施在与Mongo配对时开始破坏和/或需要直接可用于javascript而非简单形式的足够复杂的模型模式。
我打算用这个开发工作成为django战斗硬化,以便解决一个更加复杂和重要的未来应用程序。我可以整天破解这个东西并使其正常运行,但我真正感兴趣的是任何人使用Django + MongoDB + MongoEngine在数据库模式上实现CRUD的经验,该模式不是以形式为中心(想想更多的嵌套元数据) )。
感谢。
model.py :使用mongoengine字段类型。
class MongoEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, VirtualPageModel):
data_dict = (o.to_mongo()).to_dict()
if isinstance(data_dict.get('_id'), ObjectId):
data_dict.update({'_id': str(data_dict.get('_id'))})
return data_dict
else:
return JSONEncoder.default(self, o)
class SubTypeModel(EmbeddedDocument):
filename = StringField(max_length=200, required=True)
page_num = IntField(required=True)
class VirtualPageModel(Document):
volume = StringField(max_length=200, required=True)
start_physical_page_num = IntField()
physical_pages = ListField(EmbeddedDocumentField(SubTypeModel),
default=list)
error_msg = ListField(StringField(),
default=list)
def save(self, *args, **kwargs):
print('In save: {}'.format(kwargs))
for k, v in kwargs.items():
if k == 'physical_pages':
self.physical_pages = []
for a_page in v:
tmp_pp = SubTypeModel()
for p_k, p_v in a_page.items():
setattr(tmp_pp, p_k, p_v)
self.physical_pages.append(tmp_pp)
else:
setattr(self, k, v)
return super(VirtualPageModel, self).save(*args, **kwargs)
views.py :我在视图中的尝试
class VolumeSplitterView(View):
#initial = {'key': 'value'}
template_name = 'click_model/index.html'
vol = None
start = 0
end = 20
def get(self, request, *args, **kwargs):
self.vol = self.kwargs.get('vol', None)
records = self.get_records()
records = records[self.start:self.end]
vp_json_list = []
img_filepaths = []
for vp in records:
vp_json = json.dumps(vp, cls=MongoEncoder)
vp_json_list.append(vp_json)
for pp in vp.physical_pages:
filepath = get_file_path(vp, pp.filename)
img_filepaths.append(filepath)
data_dict = {
'img_filepaths': img_filepaths,
'vp_json_list': vp_json_list
}
return render_to_response(self.template_name,
{'data_dict': data_dict},
RequestContext(request))
def get_records(self):
return VirtualPageModel.objects(volume=self.vol)
def post(self, request, *args, **kwargs):
if request.is_ajax:
vp_dict_list = json.loads(request.POST.get('data', []))
for vp_dict in vp_dict_list:
o_id = vp_dict.pop('_id')
original_doc = VirtualPageModel.objects.get(id=o_id)
try:
original_doc.save(**vp_dict)
except Exception:
print(traceback.format_exc())