3

我的 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 提交表单 - 我不确定这会对如何实现这个想法产生任何影响。再次感谢汤姆的帮助:)

4

1 回答 1

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!

于 2012-05-04T04:09:24.963 回答