django-mptt似乎决定让我失去理智.我正在尝试做一些相对简单的事情:我要删除一个节点,并且需要对节点的子节点做一些合理的事情.也就是说,我想将它们提升一级,这样他们就是现在父母的父母.
也就是说,如果树看起来像:
Root
|
Grandpa
|
Father
| |
C1 C2
Run Code Online (Sandbox Code Playgroud)
我要删除父亲,并希望C1和C2成为爷爷的孩子.
这是我正在使用的代码:
class Node(models.Model):
first_name = models.CharField(max_length=80, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
def reparent_children(self, parent):
print "Reparenting"
for child in self.get_children():
print "Working on", child.first_name, "to parent", parent.email
parent = Node.objects.get(id=parent.id)
child.move_to(parent, 'last-child')
child.save()
Run Code Online (Sandbox Code Playgroud)
所以我打电话给:
father.reparent_children(grandpa)
father.parent = None
father.save()
Run Code Online (Sandbox Code Playgroud)
这很有效 - 差不多.孩子们报告他们的父母为爷爷:
c1.parent == grandpa # True
Run Code Online (Sandbox Code Playgroud)
爷爷的孩子中有C1和C2
c1 in grandpa.children.all() # True
Run Code Online (Sandbox Code Playgroud)
然而,Root拒绝了这些孩子.
c1.get_root() == father # c1's root is father, instead of Root
c1 …Run Code Online (Sandbox Code Playgroud) 这是我使用的模型:
class Comment(MPTTModel):
comment = models.CharField(max_length=1023)
resource = models.ForeignKey('Resource')
created_at = models.DateTimeField(auto_now_add=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
author = models.ForeignKey(User)
class MPTTMeta:
order_insertion_by = ['created_at']
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试从管理站点添加评论时,我得到:
ValueError at /admin/app/comment/add/
Cannot use None as a query value
Run Code Online (Sandbox Code Playgroud)
我的模特出了什么问题吗?我觉得django-mptt尝试获取DateTimeField,而它仍然是"None",之后它已在db级别设置.
我正在创建一个将同步两个数据库的脚本.数据库中有一个数据应该存储为树,所以我使用django-mptt作为新数据库.当我同步DB时,我从旧数据库中选择新数据,并将其保存在新数据库中.
我想知道是否有更好的方法将新节点添加到树中?现在看起来是下一个方式:
...
# Add new data to DB
for new_record in new_records:
# Find appropriate parent using data in 'new_record'
parent = get_parent(new_record)
# Create object which should be added using data in 'new_record'
new_node = MyMPTTModel(...)
new_node.insert_at(parent, save = True)
# Similar to:
# new_node.insert_at(parent, save = False)
# new_node.save()
Run Code Online (Sandbox Code Playgroud)
但它工作得很慢.我认为它以这种方式工作,因为每次调用该insert_at(..., save = True)方法后都django-mptt应该将新节点写入数据库并修改已经存在于数据库中的记录left和right键.
有没有办法在django-mptt每次调用时修改查询insert_at,然后在我打电话时将所有更改应用到一起save?或者你知道如何减少执行时间吗?
提前致谢.
有两个众所周知的用于创建树结构的Django包:django-treebeard和django-mptt.最近Django CMS开始使用django-treebeard而不是django-mptt.Wagtail CMS也使用django-treebeard.
是什么让django-treebeard成为比django-mptt更优选的选择?
我正在开发一个网站,需要标记不同类型的内容,这有利于使用django-taggit.但是,如果标签被在其自然的层次结构数据库中表示,这有利于使用Django-MPTT或者Django的树胡,这将是非常有益的.
将taggit的通用标记功能与mptt/treebeard提供的树结构集成的最佳解决方案是什么?
我做了教程" http://django-mptt.github.com/django-mptt/tutorial.html "中的步骤
但它仍然给我导入错误,我仔细检查mptt的代码,发现类mptt>模型文件中存在类MPTTMODEL
Validating models...
Unhandled exception in thread started by <bound method Command.inner_run of <django.contrib.staticfiles.management.commands.runserver.Command object at 0x1ec4710>>
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/commands/runserver.py", line 91, in inner_run
self.validate(display_num_errors=True)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/base.py", line 266, in validate
num_errors = get_validation_errors(s, app)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/core/management/validation.py", line 30, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/loading.py", line 158, in get_app_errors
self._populate()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/loading.py", line 67, in _populate
self.load_app(app_name)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/db/models/loading.py", line 88, in load_app
models = import_module('.models', app_name)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4-py2.7.egg/django/utils/importlib.py", line …Run Code Online (Sandbox Code Playgroud) 如何序列化django-mptt树Tastypie?
我想用django-mptt的cache_tree_children().我尝试过应用不同的Tastypie钩子,但它会抛出一个错误.
我想有一个树模仿文件系统与文件夹和文件.文件夹和文件将由具有不同字段属性的不同模型定义.
楷模:
from mptt.models import MPTTModel, TreeForeignKey
class Folder(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
name = models.CharField(max_length=50)
type = models.CharField(max_length=50)
class File(MPTTModel):
parent= TreeForeignKey(Document)
filename = models.CharField(max_length=255)
encoding = models.CharField(max_length=20)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)
创建一些文件夹和文件:
from shapefile.models import Folder, File
root = Folder.objects.create(name="Root")
download = Folder.objects.create(name="Download", parent=root)
upload = Folder.objects.create(name="Upload", parent=root)
File.objects.create(filename="Test", encoding="UTF-8", parent=download)
Run Code Online (Sandbox Code Playgroud)
Shoul有:
> Root
> --Download
> ----Test
> --Upload
Run Code Online (Sandbox Code Playgroud)
如何在视图和模板中检索此树?
编辑:
文件不作为文件夹的节点插入:
file = File.objects.get(filename="Test")
file.get_ancestors()
>>> []
Run Code Online (Sandbox Code Playgroud) 以下是我的代码:
class File(MPTTModel):
name=models.CharField(max_length=36, primary_key=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
num=models.IntegerField(null=True)
class MPTTMeta:
order_insertion_by = ['name']
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下代码序列化此类:
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class FileSerializer(serializers.ModelSerializer):
parent=RecursiveField(many=True)
class Meta:
model = File
fields=('name','num','parent')
Run Code Online (Sandbox Code Playgroud)
但我失败了,我只能输出这棵树的根节点的内容。似乎序列化器无法访问根的孩子,进一步访问孩子的孩子......具体问题是在输出中, 'parent' 显示为 'null',但实际上它有 4 个孩子,每个孩子都包含几个后代。我的代码有什么问题?谢谢大家帮助我!
我只能想出这样的解决方案:
import json
from mptt.utils import tree_item_iterator
from rest_framework import generics
from rest_framework.response import Response
from .models import Category
def tree_family_items_to_json(instances):
data = ''
channel = '"{}"'.format(instances[0].channel.slug)
for category, structure in tree_item_iterator(instances):
if structure['new_level']:
data += '{'
else:
data += '],'
data += '"channel": {}'.format(channel)
data += '},{'
data += '"slug": "{}",'.format(category.slug)
data += '"name": "{}",'.format(category.name)
data += '"subcategories": ['
for level in structure['closed_levels']:
data += '],'
data += '"channel": {}'.format(channel)
data += '}'
return …Run Code Online (Sandbox Code Playgroud) django ×10
django-mptt ×10
python ×5
database ×1
django-admin ×1
integration ×1
mptt ×1
performance ×1
tagging ×1
tastypie ×1