2

I want to have a Django form in which a user can add multiple stop_name,stop_longitude,stop_latitude using the Add more button inside. Let's suppose a user has 3 stop_names so he will have to click on the Add more twice. And on each add more above fields will populate again. I am new to Django so I need some help.

This is my model

class SupplyChainStops(models.Model):
    ingredient = models.ForeignKey(Ingredients, null=True, on_delete=models.CASCADE)
    stop_name = ArrayField(models.CharField(max_length=1024, null=True, blank=True))
    stop_longitude = ArrayField(models.CharField(max_length=500, null=True, blank=True))
    stop_latitude = ArrayField(models.CharField(max_length=500, null=True, blank=True))
The knight
  • 87
  • 1
  • 10
  • 1
    That is what `FormSet`s are all about https://docs.djangoproject.com/en/4.0/topics/forms/formsets/ – Willem Van Onsem Feb 02 '22 at 10:51
  • Have you had a look at [this](https://stackoverflow.com/questions/6142025/dynamically-add-field-to-a-form/31538300) ? – Arun T Feb 02 '22 at 10:56
  • I did actually but as i am very new to Django so I am kind of stuck. – The knight Feb 02 '22 at 10:58
  • Well as i read your comment and checking your profile i think you are fairly about three years experienced in Django, but i will provide my solution anyway with formset. – Godda Feb 02 '22 at 12:05
  • 1
    I am a stackoverflow member for about three years, I said I am new to django.I have had working experience in python but mainly in flask. – The knight Feb 02 '22 at 12:15

1 Answers1

2

Okey using formset factory i very straight forward and simple to render multiple fields for user to fill in their information. First of all you would need to create forms.py in your project and then import django's formset_factory in forms. We would do something like so:

from django.forms import formset_factory
from .models import SupplyChainStops

# Here we are creating a formset to handle the maniplations of our form to
# have extra field by using the extra parameter to formset_factory
# and also we can add a delete function to allow users to be able to delete 

Formset = formset_factory(SupplyChainStops, fields=[' stop_name',' stop_longitude','stop_latitude'], extra=4, can_delete=True)
# I have set the formset to give us an extra field of four and enable users 
# to delete 

Now we are going to work on the view to handle our formset.

from django.views.generic.edit import FormView
from .forms import Formset

class formsetView( FormView):
      template_name = 'formset.html'
      form_class = Formset
      success_url = '/'
      
      

In our template we will do something like this .


<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Add">
</form>

Doing this in a function base view

from .forms import Formset

def formset_view(request):
    if request.method == 'POST':
       formset = Formset(request.POST,)
       if formset.is_valid():
          formset.save()
    else:
          formset = ()
    return render (request, 'formset.html',{'formset':formset})

In your HTML Template

<form method="post">{% csrf_token %}
    {{ formset.as_p }}
    <input type="submit" value="Add">
</form>
Godda
  • 951
  • 1
  • 10
  • 26
  • Hey, thanks for this I really appreciate can you tell me how I can do this using a function-based view. Because I have like 10,11 function-based views in my project – The knight Feb 02 '22 at 12:49
  • Yes sure i will ! – Godda Feb 02 '22 at 12:51
  • Also, it will add the 4 extra fields, but what if some user wants to add 5 or 6? – The knight Feb 02 '22 at 12:51
  • Thanks am waiting for the function-based view. It means a lot thank you – The knight Feb 02 '22 at 12:53
  • Well with formset_factory you just add the number of fields that you think would be needed in the case of the user, with the extra argument to formset factory. And add can_delete if the extra is not needed. – Godda Feb 02 '22 at 13:12
  • You can add max_num parameter to formset_factory() which gives you the ability to limit the number of forms the formset will display. – Godda Feb 02 '22 at 13:15
  • @ Abu Godda what about the ingredient which is a foreign key in this. I do not want to repeat that. i just want that to be only once. – The knight Feb 02 '22 at 13:52
  • You would just specify the field you want in the forset_factory as ( fields=[' stop_name',' stop_longitude','stop_latitude']. – Godda Feb 02 '22 at 14:09
  • I get that, but I want "ingredient" to be only once and then repeat other. – The knight Feb 02 '22 at 14:10
  • To be honest with you i really haven't come to think of that and formset doesn't support that functionality at the moment, as to specify number of individual field in each field in a model form. i read docs and haven't come across such arrangement! but you can post it as a question maybe some one might have a solution ,you never no! – Godda Feb 02 '22 at 14:19
  • But its worth investigating i will try and find a solution for you because it is an opportunity for me to learn something new. Thank you for your question. – Godda Feb 02 '22 at 14:25