保存时添加 ManyToManyField 关系,如果不存在则创建对象
Add ManyToManyField relationship on save, and create objects if they not exist
我想'attach'表单提交上的多对多关系。
例子是经典的博客标签-post关系:一个post可以有多个标签相关
在 django-admin 中它可以工作,但我不知道如何在视图中做...
我的代码:
def add_post(request):
if request.method == 'POST':
form = PostForm(data=request.POST)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.author = request.user
newentry = model_instance.save()
#some magic needed here, this will never works
for tag in model_instance.tags.all():
t = Tag.objects.get_or_create(author=request.user, title=tag.title, slug=slugify(tag.title))
model_instance.tags.add(t)
#end of magic
return HttpResponseRedirect("/blog/")
else:
form = PostForm()
return render_to_response(
'blog/add_post.html',
{'form' : form },
context_instance=RequestContext(request))
我在模板中使用 automatic tokenization from select2.js,所以我可以添加标签 "on the fly",但我不确定如何使用 django 处理它...
newentry = model_instance.save()
模型实例上的 save()
方法不会 return 任何东西,这与表单上的相同方法不同。您应该重用 model_instance
而不是使用 newentry
.
如果标签尚不存在,我还会查看 get_or_create()
以创建标签。
作为一名数据库程序员(有一点 Django 经验),我认为您应该规范化您的模型。 IE,添加第三个 table(称其为 Post 标签)并将其设置为帖子和标签之间的中介。因此,从 Post 到 Post 标签的关系将是 1:M,从标签到 Post 标签的关系将是 1:M
我有一个博客,其中在 post 和项目之间有一个 ManyToManyField,我 select 项目以 post 形式创建关系。
当您在 form.save() 上使用 commit=False 时,您需要在使用 post.save() 保存表单后使用 form.save_m2m()。
这是我的视图函数的一部分:
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
# This saves the project relation
form.save_m2m()
为了您的使用,我会尝试在您的魔法之后移动 model_instance.save() 和 form.save_m2m()。
关于 get_or_create() 的另一件事是它 returns 一个包含已获取或创建的对象的元组,以及一个关于它是否创建该对象的布尔值。所以你只需要传递 model_instance.tags.add() 创建的对象。
form = PostForm(data=request.POST)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.author = request.user
#some magic needed here, this will never works
for tag in model_instance.tags.all():
t, created = Tag.objects.get_or_create(author=request.user, title=tag.title, slug=slugify(tag.title))
model_instance.tags.add(t)
#end of magic
model_instance.save()
form.save_m2m()
我想'attach'表单提交上的多对多关系。
例子是经典的博客标签-post关系:一个post可以有多个标签相关
在 django-admin 中它可以工作,但我不知道如何在视图中做...
我的代码:
def add_post(request):
if request.method == 'POST':
form = PostForm(data=request.POST)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.author = request.user
newentry = model_instance.save()
#some magic needed here, this will never works
for tag in model_instance.tags.all():
t = Tag.objects.get_or_create(author=request.user, title=tag.title, slug=slugify(tag.title))
model_instance.tags.add(t)
#end of magic
return HttpResponseRedirect("/blog/")
else:
form = PostForm()
return render_to_response(
'blog/add_post.html',
{'form' : form },
context_instance=RequestContext(request))
我在模板中使用 automatic tokenization from select2.js,所以我可以添加标签 "on the fly",但我不确定如何使用 django 处理它...
newentry = model_instance.save()
模型实例上的 save()
方法不会 return 任何东西,这与表单上的相同方法不同。您应该重用 model_instance
而不是使用 newentry
.
如果标签尚不存在,我还会查看 get_or_create()
以创建标签。
作为一名数据库程序员(有一点 Django 经验),我认为您应该规范化您的模型。 IE,添加第三个 table(称其为 Post 标签)并将其设置为帖子和标签之间的中介。因此,从 Post 到 Post 标签的关系将是 1:M,从标签到 Post 标签的关系将是 1:M
我有一个博客,其中在 post 和项目之间有一个 ManyToManyField,我 select 项目以 post 形式创建关系。
当您在 form.save() 上使用 commit=False 时,您需要在使用 post.save() 保存表单后使用 form.save_m2m()。
这是我的视图函数的一部分:
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
# This saves the project relation
form.save_m2m()
为了您的使用,我会尝试在您的魔法之后移动 model_instance.save() 和 form.save_m2m()。
关于 get_or_create() 的另一件事是它 returns 一个包含已获取或创建的对象的元组,以及一个关于它是否创建该对象的布尔值。所以你只需要传递 model_instance.tags.add() 创建的对象。
form = PostForm(data=request.POST)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.author = request.user
#some magic needed here, this will never works
for tag in model_instance.tags.all():
t, created = Tag.objects.get_or_create(author=request.user, title=tag.title, slug=slugify(tag.title))
model_instance.tags.add(t)
#end of magic
model_instance.save()
form.save_m2m()