Django form not saving with ModelChoiceField - ForeignKey

I have multiple forms on my site that work and save info to my PostgreSQL database. I am trying to create a form to save information for my Set Model:

class Set(models.Model):
    settitle = models.CharField("Title", max_length=50)
    setdescrip = models.CharField("Description", max_length=50)
    action = models.ForeignKey(Action)
    actorder = models.IntegerField("Order number")

The Set Form looks like this. I am using ModelChoiceField to pull a list of Action name fields from the Action model, this displays on the form as a select dropdown

class SetForm(ModelForm):

    class Meta:
        model = Set
        fields = ['settitle', 'setdescrip', 'action', 'actorder']
    action = forms.ModelChoiceField(queryset = Action.objects.values_list('name', flat=True), to_field_name="id")

The view for createset is below:

def createset(request):
    if not request.user.is_authenticated():
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    elif request.method == "GET":
        #create the object - Setform 
        form = SetForm;
        #pass into it 
        return render(request,'app/createForm.html', { 'form':form })
    elif "cancel" in request.POST:
        return HttpResponseRedirect('/actions')
    elif request.method == "POST":
    # take all of the user data entered to create a new set instance in the table
        form = SetForm(request.POST, request.FILES)
        if  form.is_valid():
            form.save()
            return HttpResponseRedirect('/actions')
        else:
            form = SetForm()
            return render(request,'app/createForm.html', {'form':form})

When the form is filled in and valid and Save is pressed, nothing happens. No errors, the page just refreshes to a new form. If I don't set the action field in forms.py using (action = forms.ModelChoiceField(queryset = Action.objects.values_list('name', flat=True), to_field_name="id")) then the data saves, so that is likely where I am doing something wrong. Just not sure what?

Answers


https://docs.djangoproject.com/en/stable/ref/forms/fields/#django.forms.ModelChoiceField.queryset

The queryset attribute should be a QuerySet. values_list returns a list.

You should just define the __str__ method of your Action model and you won't have to redefine the action field in the form.

If it is set and you want to use another label, you can subclass ModelChoiceField.

The __str__ (__unicode__ on Python 2) method of the model will be called to generate string representations of the objects for use in the field’s choices; to provide customized representations, subclass ModelChoiceField and override label_from_instance. This method will receive a model object, and should return a string suitable for representing it. For example:

from django.forms import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return "My Object #%i" % obj.id

So, in your case, either set the __str__ method of Action model, and remove the action = forms.ModelChoiceField(...) line in your form:

class Action(models.Model):
    def __str__(self):
        return self.name

class SetForm(ModelForm):

    class Meta:
        model = Set
        fields = ['settitle', 'setdescrip', 'action', 'actorder']

Or either define a custom ModelChoiceField:

class MyModelChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.name

class SetForm(ModelForm):

    class Meta:
        model = Set
        fields = ['settitle', 'setdescrip', 'action', 'actorder']

    action = MyModelChoiceField(Action.objects.all())

Need Your Help

How to transform a named JsArray into a JsObject with JsZipper

json scala playframework

Let's assume either of the following two JSON snippets: