MMakela
MMakela

Reputation: 167

How to save changed fields with ModelForm?

I want to save changed values of ModelForm to database. I'm having problems even I follow this documentation if I'm right that it can be possible with initial values: Documentation- providing initial values

models.py:

class Settings(models.Model):
   url = models.URLField(max_length=100, default='https://website.com')
   maxCount = models.SmallIntegerField(default=30)

views.py:

def Settings(request):

    settingsObj = Settings.objects.get(id=1)
    form = SettingsForm(initial={'url': settingsObj.url, 'maxCount':settingsObj.maxCount}, instance=settingsObj)

    if form.is_valid():
        form.save()

forms.py:

class SettingsForm(forms.ModelForm):
    class Meta:
        model = Settings
        fields = ['url', 'maxCount']

templates

    <form class="form-horizontal" role="form" method="POST">{% csrf_token %}
  <div class="form-group">
    <div class="col-sm-offset-1 col-sm-6">
    {{ form.as_p }}
    </div>
  </div>
    <div class="form-group">        
      <div class="col-sm-offset-1 col-sm-6">
        <button type="submit" class="btn btn-primary btn-lg btn-block">Accept</button>
      </div>
    </div>
  </form>

Currently the form is showing the current values from database, but isn't saving changed data. form.is_valid() returns True, but form.save() seems to do nothing.

Upvotes: 0

Views: 697

Answers (1)

Yash Tewari
Yash Tewari

Reputation: 790

The initial argument and the instance argument in your call to SettingsForm() serve the exact same purpose, because you are using the fields of the instance individually in each field of initial.

The save() method is not working because you need to populate the form with data from request.POST.

This view should work:

def settings(request):    
    settingsObj = Settings.objects.get(id=1)
    if request.POST:
        form = SettingsForm(request.POST, instance=settingsObj)    
        if form.is_valid():
            form.save()
    else:
        form = SettingsForm(instance=settingsObj)

    context = { ..., 'form': form, ... }
    return render(request, 'template-address', context)

Upvotes: 1

Related Questions