2

I try to make a django application to create bills.

I have two tables (Bill, Delivery) and one Bill can have up to 5 deliveries.

Now I want a form for the bill and one delivery. To add or remove a delivery I want a button.

I am using class-based-views. How to realise this in django?

I have found django-extra-views, but I couldn't get it work. I have also seen this link here but this is not dynamic and function-based views.

models.py

class Bill(models.Model):
    company = models.ForeignKey(Bioenergie)
    customer = models.ForeignKey(Customer)
    price = models.DecimalField(max_digits=5,decimal_places=2)
    bill_number = models.CharField(max_length=10, null=True)
    delivery_date = models.DateField()
    date = models.DateField(null=True)


class Delivery(models.Model):
    billing_choises = (('1', 'Menge'),
                       ('2', 'Gewicht/Feuchtigkeit')
    )
    option = models.CharField(choices=billing_choises, default=1, max_length=20)
    amount = models.PositiveIntegerField(blank=True, null=True)
    humidity = models.SmallIntegerField(blank=True, null=True)
    weight = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=5)
    bill = models.ForeignKey(Bill)

Image to show what my Website should contain Blue: Forms Gray: Buttoms

Community
  • 1
  • 1
spitzbuaamy
  • 751
  • 2
  • 10
  • 25
  • Can you snow your models and explain a little what you tried? – Nil Feb 15 '14 at 14:35
  • I can't write a complete answer now, but I suggest you take a look at [Formsets](https://docs.djangoproject.com/en/1.6/topics/forms/formsets/). Or better, if you don't want to write everything, there are at least 2 projects that do what you need: [django-dynamic-formset](https://code.google.com/p/django-dynamic-formset/) and [django-dinamyc-form](https://github.com/javisantana/django-dinamyc-form). – Nil Feb 15 '14 at 20:11
  • You can also read thoses SO questions for more information: [1](http://stackoverflow.com/questions/2353710/how-would-you-make-a-dynamic-formset-in-django) and [2](http://stackoverflow.com/questions/501719/dynamically-adding-a-form-to-a-django-formset-with-ajax) – Nil Feb 15 '14 at 20:13

2 Answers2

4

Your question is twofold:

  1. make Django work with a Form and a Formset on a single View
  2. Make the Formset JavaScripty (tm)

Well...

1) Form and Formset together on a View

Normally this would include old-style (function-based) views, because class-based views don't support more then one Form, and no FormSets, let alone together. One could take, say, UpdateView, and then "manually" make it handle a FormSet, but that's just ugly, better go with old-style views all the way in that case, IMHO.

But! Thanks to the AWESOME django-extra-views, We can do stuff like this:

forms.py:

from extra_views import InlineFormSet

class DeliveryInlineFormSet(InlineFormSet):
    model = Delivery
    extra = 2  # we'll need to make it "0" for the JS later on

views.py:

from extra_views import CreateWithInlinesView, UpdateWithInlinesView

class CreateBillView(CreateWithInlinesView):
    model = Bill
    inlines = [DeliveryInlineFormSet, ]
    success_url = reverse_lazy('bills')


class UpdateBillView(UpdateWithInlinesView):
    model = Bill
    inlines = [DeliveryInlineFormSet, ]
    success_url = reverse_lazy('bills')

bill_form.html:

<form method="POST" action="">
    {{ form }}

    {% for formset in inlines %} 
        <hr />
        {# we're going to take advantage of the fact that we know there is only one inline #}
        <h3>Deliveries</h3>
        {{ formset.management_form }}
        {% for subform in formset %}
            <div class="subform">
                {{ subform }}
            </div>
        {% endfor %}
        {# we'll add some JS here #}
    {% endfor %}
    <div>
        <hr />
        {% csrf_token %}
        <input type="submit" value="Save" name="save" />
    </div>
</form>

That's it, a working non-JS Form+FormSet create and update View.

2) Make FormSet JavaScripty (tm)

There is somewhat old project for this, but it still works: django-dynamic-formset

To get it to work:

  • load jQuery (probably not 2.x, but I haven't tested it)
  • load the jquery.formset.js
  • set extra = 0 in forms.py
  • find the {# we'll add some JS here #} in the template above, and replace it with:

.

<script type="text/javascript">
    $(function(){
        $('.subform').formset({
           prefix: '{{ formset.prefix }}'
        });
    });
</script>

Tadaaa! All that's left to do is add some CSS...

frnhr
  • 12,354
  • 9
  • 63
  • 90
  • Thank you a lot. This works fine for me. This is my fist django project and so I wouldn't be able to do this wihout your help – spitzbuaamy Feb 17 '14 at 18:16
0

You can achieve this in template using javascript

Hope this helps : http://sunnyarorablog.wordpress.com/2014/04/07/create-dynamic-forms-using-django-and-javascript/

sunny
  • 708
  • 11
  • 23