3

私のdjangoプロジェクトにjsonfieldがあり、テキストフィールドを追加するボタンをどのように持つことができるのか疑問に思っていました

例えば:

ステップのリストがあり、ボタンをクリックしてステップを追加したい (電子メールに添付ファイルを追加するのと同様に) そして、これらすべてを jsonfield にパックしたい

だから私の2つの質問は

ボタンを使用してテキスト フィールドを追加する方法と、テキスト フィールドを 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 に答える