Search code examples
djangojsonformssimplejson

Django add textfield on click


I am writing a django recipe website and have a question about JSON Field and forms

I am trying to write the create recipe function for the site and wanted to do two things:

  1. I want to add text fields on mouse click similarly to adding attachments with e-mails. I want to use JSONField to do so (unless picklefield is better)

  2. i want the user to be able to edit the recipe in one textfield. I was hoping i could pack all of the steps into one text field and allow them to edit that field and then unpack them back into the steps. otherwise it might get confusing for the user to have to edit each individual step.

here are my models from the django project:

class Cookbook(models.Model):
    def __unicode__(self):
        return self.name
    name = models.CharField(max_length=50)
    pub_date = models.DateTimeField('date published')
    user = models.ForeignKey(User, related_name='cookbooks')
    recipes = models.ManyToManyField('Recipe', related_name = 'cookbooks')


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)
    ingredients = JSONField()
    steps = JSONField()
    prep_time = models.IntegerField()

Here is the view in which I create a new recipe. Right now I am unsure how to use the JSONField in my view.

I found this link but it states "Finally, I'm not sure how to interact with forms yet, so that realm is a bit murky." Seeing that I am using a form, has this been resolved?

def createrecipe(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/index/')
    else:
        if request.method == 'POST':
            form = RecipeForm(request.POST)
            if form.is_valid():
                recipe = form.save(commit=False)
                recipe.original_cookbook = request.user.cookbooks.all()[0]
                recipe.pub_date = datetime.datetime.now()
                recipe.save()
                user = request.user
                cookbooks = user.cookbooks
                cookbook = cookbooks.all()[0]
                cookbook.recipes.add(recipe)
                return HttpResponseRedirect('/account')
        else:
            form = RecipeForm()

        return render_to_response('cookbook/createrecipe.html',
                                    {'form':form},
                              context_instance=RequestContext(request))

here is the createrecpe.html block content:

{% block content %}
    <form action="." method="POST">
        <table>
            {% csrf_token %}
            {{ form.as_table }}
        </table>
        <p><input type="submit" value="Submit"></p>
    </form>
{% endblock %}

I am having a hard time bridging the gap between the JSONField model and the view to display/enter text into the JSON field. I also am confused how to display the jsonfield in a template.

thank you for any help this has really been discouraging me,

snackerfish


Solution

  • You can use a formset here. In your case - take django-jsonfield or django-picklefield to avoid manual converting to/from data on object's saving and retrieving, and create a formset providing empty list on init.

    You can manipulate it on client side using js, but do not forget to increment forms count in TOTAL_FORMS hidden input. After POSTing the form and cleaning the data you'll have formset.cleaned_data() which you could put to your PickleField without any aditional processing (and data from the field can be put as initial to formset if you'll need to edit the recipe).