3

I think what I'm trying to achieve is not hard, but I have no clue how to do it hehehehe !

Basically what I need is the feature that we have in Django Admin, when you are creating a new object, if you have a Foreign Key, you can add new data (opening a pop-up), save it and then the select box updates automatically.

What I have is this form:

enter image description here

I know that would be easy to do it with some Javascript, but my point is, Django has some rules, and as far I know, I can't add new data to a form already created, right? Otherwise Django won't validate this form. How could I achieve this?

PS: "Local" is the select box where I want to add new data. The user should be able to create a new Local on this page, instead of going to another page to do it. Thanks :)

Lara
  • 2,170
  • 6
  • 22
  • 43
  • Please take a look at http://stackoverflow.com/questions/7782479/django-reverse-engineering-the-admin-sites-add-foreign-key-button it might help you. – Felippe Raposo May 23 '16 at 21:27

2 Answers2

1

Here your question:

I can't add new data to a form already created, right? Otherwise Django won't validate this form. How could I achieve this?

Then the answer:

you are right, django will check values match form value rules. But:

realize that your main form is invoked for twice: on GET and on POST. Between both form executions you make changes on database values trhough your new form. That means that in second main form invocation the value added to database is available:

field1 = forms.ModelChoiceField(queryset=  ***1*** )

***1***: on second invocation new value is already available on field1.

Then, you don't should to be afraid about this subject, the new value will be available on form on your main form POST request.

dani herrera
  • 48,760
  • 8
  • 117
  • 177
0

Nothing wrong with updating the value using javascript as long the key in your new combo box has the right key in the database then it should be ok.

Call this function after you saved the last entry.

function refreshLocal(){
    $.get(window.location.href, '', function(html){
        // change the id to the local combox's id
        var serverLocalDropBox = $(html).find('#id_local');   
        if (serverLocalDropBox.length){
            $('#id_local').replaceWith(serverLocalDropBox);
        }
    })
}

If you don't want to use javascript solution, you can post the form with refresh flag and on the server side if you see that flag just don't validate and return the form as is. Since you have a new entry in the foreignkey it will automatically update the queryset to include the new entry.

function serverRefreshLocal(){
        var $form = $('#your_form_id');
        $form.append('<input type="hidden" name="refresh" value="true" />');

        // you can use ajax submit and ajax refresh here if you don't want to leave the page
        $form.submit();
    }

// Server Side

def your_form_post_view(request):

    if request.POST.get('refresh', 'false') == 'true':
        # initial is the trick to save user input
        your_form = YourForm(initial=request.POST)
        context = {
            'form': your_form,
        }
        return render(request, 'your_template.html', context)

    # your view code goes here
Du D.
  • 5,062
  • 2
  • 29
  • 34