将面向用户的自定义表单添加到 Django 应用程序(使用 selectize 和 taggit)
Add a custom user-facing form to Django app (uses selectize and taggit)
我是 django 的新手,我正在尝试弄清楚如何使用 taggit-selectize widget (or django-taggit) 创建表单。我在网上找到的所有内容都指的是它使用管理页面,但我希望这些标签面向用户且可编辑 - 就像我在 post 下面创建的标签一样。到目前为止,我已经确定我需要使用小部件创建一个表单:
# models.py
from taggit_selectize.managers import TaggableManager
tags = TaggableManager()
# forms.py
from taggit_selectize.widgets import TagSelectize
from .models import MyModel
class TagForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('tags',)
widgets = {'tags': TagSelectize(),}
但我不知道如何将此表单包含在我的模板中,以便它出现在我的 MyModel
对象旁边。理想情况下,我想我希望它表现得像 django-fluent-comments,在那里我可以调用 {% render_comment_form for obj %}
并结束它。
更新
我编辑了 views
(见下文),现在可以访问模板中的表单,但我似乎无法提交我的标签(理想情况下这也不会触发重定向) .
# views.py
from .forms import TagForm
def show_tags(request):
return render(request, 'tags.html', {'tagform' : TagForm})
# tags.html
<div>
{{ tagform.media }}
{{ tagform.as_p }}
</div>
所以,我终于想通了。它涉及将标签形式包装在 <form>
标签中并捕获 POST 请求。作为记录,这是一个项目的一部分,该项目涉及使用 Haystack 来 return 我随后要标记的结果列表。我的 views.py
是一个 SearchView
的子类,而不是像我在这里那样定义一个函数 (show_tags()
),而不是每页一个对象我有多个。
对于页面上的对象 obj,您有以下内容
# views.py
from .forms import TagForm
from .models import MyModel
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
def show_tags(request):
# Perhaps the request specifies the object, but
# for simplicity's sake we just pick a specific model instance
object = MyModel.objects.filter(pk = 123)
return render(request, 'tags.html', {'tagform' : TagForm,
'obj' : MyModel})
@require_POST
@csrf_exempt
def create_tag(request):
# See javascript below for creation of POST request
data = request.POST
tag_text_raw = data.get('tag_data')
# clean_tag() not shown, but it splits the serialized
# tag_text_raw and returns a list of strings
tag_text_clean = clean_tag(tag_text_raw)
obj_pk = data.get('obj_pk')
#save tags to document
doc = DocInfo.objects.get(pk = obj_pk)
doc.tags.add(*tag_text_clean)
# not strictly necessary; mainly for logging
response_data = {'tag_text': tag_text_clean,
'obj_pk': obj_pk
}
return JsonResponse(response_data)
因此show_tags
使用render
将信息发送到模板,然后模板可以访问这些对象。这对我来说最初是没有意义的。
# tags.html (extends base.html)
{% block scripts %}{{ block.super }}
<script type="text/javascript" src="{{ STATIC_URL }}js/ajaxtag.js"></script>
{{ tagform.media }}
{% endblock %}
{{ obj.text }}
<form method="post" action="create_tag/" id="tag-form-{{ obj.pk }}" name="tag-form-obj" data-object-id={{ obj.pk }}>
{{ tagform.as_p }}
<input type="submit" name ="tag-form-input" value="Add Tags" />
</form>
我们可以通过 javascript:
捕获 POST 请求
#ajaxtag.js
(function($)
{
// A stripped-down version of ajaxcomments.js from fluent_comments
// See that file for further expansions
$.fn.ready(function () {
var tagform = $('form[name="tag-form-obj"]');
if (tagform.length > 0) {
// Detect last active input.
// Submit if return is hit
tagform.find(':input').focus(setActiveInput).mousedown(setActiveInput);
tagform.submit(onTagFormSubmit);
}
});
function onTagFormSubmit(event)
{
event.preventDefault(); // prevents redirect
var form = event.target;
create_tag(form);
return false;
}
function create_tag(form)
{
console.log("create_tag is working!") // sanity check
var $form = $(form);
var tag_text = $form.serialize();
var url = $form.attr('action');
var obj_id = $form.attr('data-object-id')
$.ajax({
url : url,
type: "POST",
data: { tag_data: tag_text, obj_pk: obj_id},
success: function (data) {
data;
console.log(data);
console.log('success');
},
error: function (xhr, errmsg, err) {
// Return error to console
console.log(xhr.status + ": " + xhr.responseText)
}
});
}
function setActiveInput() {
active_input = this.name;
}
})(window.jQuery);
最后,urls.py
将请求发送回 create_tag()
# urls.py
from .views import create_tag
...
url(r'^create_tag', create_tag, name = 'tag-form')
...
我是 django 的新手,我正在尝试弄清楚如何使用 taggit-selectize widget (or django-taggit) 创建表单。我在网上找到的所有内容都指的是它使用管理页面,但我希望这些标签面向用户且可编辑 - 就像我在 post 下面创建的标签一样。到目前为止,我已经确定我需要使用小部件创建一个表单:
# models.py
from taggit_selectize.managers import TaggableManager
tags = TaggableManager()
# forms.py
from taggit_selectize.widgets import TagSelectize
from .models import MyModel
class TagForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('tags',)
widgets = {'tags': TagSelectize(),}
但我不知道如何将此表单包含在我的模板中,以便它出现在我的 MyModel
对象旁边。理想情况下,我想我希望它表现得像 django-fluent-comments,在那里我可以调用 {% render_comment_form for obj %}
并结束它。
更新
我编辑了 views
(见下文),现在可以访问模板中的表单,但我似乎无法提交我的标签(理想情况下这也不会触发重定向) .
# views.py
from .forms import TagForm
def show_tags(request):
return render(request, 'tags.html', {'tagform' : TagForm})
# tags.html
<div>
{{ tagform.media }}
{{ tagform.as_p }}
</div>
所以,我终于想通了。它涉及将标签形式包装在 <form>
标签中并捕获 POST 请求。作为记录,这是一个项目的一部分,该项目涉及使用 Haystack 来 return 我随后要标记的结果列表。我的 views.py
是一个 SearchView
的子类,而不是像我在这里那样定义一个函数 (show_tags()
),而不是每页一个对象我有多个。
对于页面上的对象 obj,您有以下内容
# views.py
from .forms import TagForm
from .models import MyModel
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
def show_tags(request):
# Perhaps the request specifies the object, but
# for simplicity's sake we just pick a specific model instance
object = MyModel.objects.filter(pk = 123)
return render(request, 'tags.html', {'tagform' : TagForm,
'obj' : MyModel})
@require_POST
@csrf_exempt
def create_tag(request):
# See javascript below for creation of POST request
data = request.POST
tag_text_raw = data.get('tag_data')
# clean_tag() not shown, but it splits the serialized
# tag_text_raw and returns a list of strings
tag_text_clean = clean_tag(tag_text_raw)
obj_pk = data.get('obj_pk')
#save tags to document
doc = DocInfo.objects.get(pk = obj_pk)
doc.tags.add(*tag_text_clean)
# not strictly necessary; mainly for logging
response_data = {'tag_text': tag_text_clean,
'obj_pk': obj_pk
}
return JsonResponse(response_data)
因此show_tags
使用render
将信息发送到模板,然后模板可以访问这些对象。这对我来说最初是没有意义的。
# tags.html (extends base.html)
{% block scripts %}{{ block.super }}
<script type="text/javascript" src="{{ STATIC_URL }}js/ajaxtag.js"></script>
{{ tagform.media }}
{% endblock %}
{{ obj.text }}
<form method="post" action="create_tag/" id="tag-form-{{ obj.pk }}" name="tag-form-obj" data-object-id={{ obj.pk }}>
{{ tagform.as_p }}
<input type="submit" name ="tag-form-input" value="Add Tags" />
</form>
我们可以通过 javascript:
捕获 POST 请求 #ajaxtag.js
(function($)
{
// A stripped-down version of ajaxcomments.js from fluent_comments
// See that file for further expansions
$.fn.ready(function () {
var tagform = $('form[name="tag-form-obj"]');
if (tagform.length > 0) {
// Detect last active input.
// Submit if return is hit
tagform.find(':input').focus(setActiveInput).mousedown(setActiveInput);
tagform.submit(onTagFormSubmit);
}
});
function onTagFormSubmit(event)
{
event.preventDefault(); // prevents redirect
var form = event.target;
create_tag(form);
return false;
}
function create_tag(form)
{
console.log("create_tag is working!") // sanity check
var $form = $(form);
var tag_text = $form.serialize();
var url = $form.attr('action');
var obj_id = $form.attr('data-object-id')
$.ajax({
url : url,
type: "POST",
data: { tag_data: tag_text, obj_pk: obj_id},
success: function (data) {
data;
console.log(data);
console.log('success');
},
error: function (xhr, errmsg, err) {
// Return error to console
console.log(xhr.status + ": " + xhr.responseText)
}
});
}
function setActiveInput() {
active_input = this.name;
}
})(window.jQuery);
最后,urls.py
将请求发送回 create_tag()
# urls.py
from .views import create_tag
...
url(r'^create_tag', create_tag, name = 'tag-form')
...