我的django项目中有一个jsonfield,我想知道如何使用按钮添加文本域
例如:
我有一个步骤列表,我想点击一个按钮添加一个步骤(类似于在电子邮件中添加附件)然后我想将所有这些包装到一个jsonfield
所以我的两个问题是
如何通过按钮添加文本字段以及如何将文本字段打包到jsonfield中
非常感谢没有包含任何代码,因为我认为没有必要
凯蒂
编辑:添加代码:
这是我为我的食谱创建一个新配方对象的视图。这也是处理包含jsonfields的表单的视图:
def createrecipe(request):
if request.method == 'POST':
form = RecipeForm(request.POST)
if form.is_valid():
form = RecipeForm(initial = {'original_cookbook' : request.user.cookbooks.all()[0]})
form = form.save()
t = loader.get_template('cookbook/create_form.html')
c = RequestContext(request, {
'form': form,
})
data = {
'replace': True,
'form': t.render(c),
'success': True,
}
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='text/plain')
else:
form = RecipeForm(request.POST)
t = loader.get_template('cookbook/create_form.html')
c = RequestContext(request, {
'form':form,
})
data ={
'form': t.render(c),
'success': False,
}
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='text/plain')
这是我的食谱的model.py(jsonfields所在的位置):
class Recipe(models.Model):
def __unicode__(self):
return self.name
original_cookbook = models.ForeignKey(Cookbook)
name = models.CharField(max_length=200)
author = models.CharField(max_length= 100)
picture = models.ImageField(upload_to = 'Downloads', blank=True)
pub_date = models.DateTimeField('date published', auto_now_add=True, blank=True)
type = models.CharField(max_length = 2, choices=TYPE_CHOICES)
ingredients = JSONField()
steps = JSONField()
prep_time = models.IntegerField()
这是我的帐户视图:
def account(request):
user = request.user
if request.user.is_authenticated():
cookbooks = user.cookbooks
if cookbooks.all().exists():
cookbook = cookbooks.all()[0]
form = RecipeForm(initial = {'original_cookbook' : request.user.cookbooks.all()[0]})
recipe_list = cookbook.recipes.all()
else:
raise Http404
else:
return HttpResponseRedirect('/accounts/login')
t = loader.get_template('cookbook/account.html')
c = RequestContext(request, {
'form': form,
'recipe_list': recipe_list
})
return HttpResponse(t.render(c))
这是表单的模板: create_form.html表单的操作指向创建配方视图
<body>
<form action="{% url cookbook.views.createrecipe %}" method="POST" name="recipeform" id="createrecipeform">
<table>
{% csrf_token %}
{{ form.as_table }}
</table>
<p><input type="submit" value="Submit"></p>
</form>
<form class="task-form" action="." method="POST">
<button class=".task-add-button" value="Add Task">
{% csrf_token %}
{{ TaskFormSet.as_p }}
</form>
</body>
这是处理create_recipe页面的帐户页面的模板... account.html
{% extends "cookbook/base.html" %}
{% load pagination_tags %}
{% load comments %}
<h1>{{ user }}'s Cookbook</h1>
<ul>
{% block nav-cookbooks %}
<li><a class="nav-inactive" href="/cookbooks/">Cookbooks</a></li>
{% endblock %}
{% block nav-account %}
<li><a class="nav-active" href="/account/">My Cookbook</a></li>
{% endblock %}
</ul>
{% block content %}
{% autopaginate recipe_list 6 %}
<div id="recipe_cont">
{% for recipe in recipe_list %}
<div class="recipe">
<div class="button">
<a href="{% url cookbook.views.userrecipe recipe.id %}" style="display: none;"></a>
<img src="{{ STATIC_URL }}chicknbraw.jpg" alt="" height="70" width="70" style="display:inline;" />
<h4>{{ recipe.name }}</h4>
</div>
<h5>{{ recipe.author }}</h5>
<h5>Prep Time: {{ recipe.prep_time }} minutes</h5>
<h6><a href="/addrecipe/{{ recipe.id }}">Add Recipe</a>
<a href="/removerecipe/{{ recipe.id }}">Remove Recipe</a></h6>
</div>
{% endfor %}
</div>
<div id="popupContact" class="popup">
<a id="popupContactClose" style="cursor:pointer;float:right;">x</a>
<p id="contactArea">
<h1 style="text-align:center">Create New Recipe</h1>
{% include 'cookbook/create_form.html' %}
</p>
</div>
<div id="backgroundPopup">
</div>
<div id="col2-footer">
{% paginate %}
<p id="recipe_order_text"> order by: <a href="/userbook/ordered/name">abc</a>|<a href="/userbook/ordered/date">date</a>
</div>
{% endblock %}
{% block footer %}
<a class="create" style="cursor:pointer" >Create New Recipe</a>
{% endblock %}
base.html文件:
{% load i18n %}
{% block doctype %}<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
{% endblock %}
{% block head %}
<head>
<title>{% block title %}Recipeek{% endblock %}</title>
<script type="text/javascript">
$(document).ready(function(){
var form = $('form#createrecipeform');
form.submit(function(e) {
e.preventDefault();
console.log('ajax form submission function called successfully.');
//form = $(this);
console.log(form)
var serialized_form = form.serialize();
$.ajax({ type: "POST",
url: $(this).attr('action'),
data: serialized_form,
success: (function(data) {
console.log('ajax success function called successfully.');
data = $.parseJSON(data);
if (data.success) {
console.log('success');
var newForm = data.form;
form.replaceWith(newForm);
} else {
console.log('failure');
var newForm = data.form;
form.replaceWith(newForm);
}
})
});
return false;
});
});
</script>
</head>
{% endblock %}
{% block body %}
<body>
{% block header %}
<div id="header"></div>
{% endblock %}
<div id="left_pane">
<div id="left_pane-container">
<div id="logo"><img src= "/static/recipeek_logo.png" style="padding-left:10px;" /></div>
<div id="left_pane-items">
<div id="nav_out">
<ul id="nav_outlist">
<li><a href="/aboutus">about us</a></li>
<li><a href="/contact">contact</a></li>
<li><a href="/glossary">glossary</a></li>
</ul>
</div><!--nav_out-->
</div><!--left_pane-items-->
</div><!--left_pane-container-->
</div><!--left_pane-->
{% block container %}
<div id="container">
<div id="container_header">
<div id="horz_nav">
<ol>
<li id="cookbook_link">{% block nav-cookbooks %}<a href="/cookbooks/">Cookbooks</a> {% endblock %}</li>
<li id="account_link">{% block nav-account %}<a href="/account/">My Cookbook</a>{% endblock %}</li>
</ol>
</div>
<div id="container_header-items">
<a href="{% url index %}">{% trans "Home" %}</a> |
{% if user.is_authenticated %}
{{ user.username }}
(<a href="{% url auth_logout %}">{% trans "Log out" %}</a> |
<a href="{% url auth_password_change %}">{% trans "Change password" %}</a>)
<form action="/search/" method="get">
<input type="text" name="q" id="id_q" value="Search" onfocus="if(this.value==this.defaultValue)this.value='';" onblur="if(this.value=='')this.value=this.defaultValue;"/>
</form>
{% else %}
<a href="{% url auth_login %}">{% trans "Log in" %}</a>
{% endif %}
</div><!--header-items-->
</div><!--header-->
<div id="col2">
<div id="col2-header"></div>
{% block content %}{% endblock %}
</div>
<div id="footer">
{% block footer %}
{% endblock %}
</div>
</div>
{% endblock %}
</body>
{% endblock %}
</html>
我认为这是所有相关的代码。
我想我还应该提一下我使用ajax提交表单 - 我不确定这会对如何实现这个想法产生任何影响。再次感谢帮助汤姆:)
答案 0 :(得分:0)
好吧凯蒂,你要做的就是在前端设置一些javascript。
<form class="task-form" action="." method="POST">
<button class=".task-add-button" value="Add Task">
{{ TaskFormSet.as_p }}
</form>
<script>
var $form = $('.task-form')
, $button = $form.find('.task-add-button')
, template = '{{ TaskFormSet.empty_form.as_p }}'
, num_formsets = $form.find('input[name=TOTAL_FORMS]').val();
$button.on('click', function(){
var formset_html = template.replace('__prefix__', 'form-'+(++num_formsets);
$(formset_html).appendTo($form); // Creates new input
return false;
});
</script>
然后您将需要一个能够处理此列表的表单。 https://docs.djangoproject.com/en/dev/topics/forms/formsets/
from django.forms.formsets import formset_factory
class TaskForm(Form):
title = CharField()
... any number of extra fields
TaskFormSet = formset_factory(TaskForm, can_order=True, can_delete=True, extra=1)
# In your view
instance = TaskModel.objects.get(...)
tasks_formset = TaskFormSet(request.POST, initial=instance.tasks_json)
context['TaskFormSet'] = tasks_formset
if request.method == 'POST' and tasks_formset.is_valid():
instance.tasks_json = [task.cleaned_data for task in tasks_formset]
instance.save()
我希望这对您有所帮助,欢迎来到StackOverflow!