mongoengine知道何时删除文档

时间:2015-11-22 22:35:56

标签: django mongodb django-models django-views mongoengine

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())

0 个答案:

没有答案