catastropic
catastropic

Reputation: 61

django error "invalid literal for int() with base 10: 'a' " while posting form

I am getting this error while form submission. I know what exactly is causing this error but i seem to be lost here. Actually im trying to use the M2M field as a charfield in my form. According to documentation, the M2M field takes only the list of valid ids and im passing a list of texts. This is the main cause for the error as far as i am informed. Any idea how i can get rid of this error

I have a model structure of:

class Question(models.Model):
    topic = models.ForeignKey(Topic, null=True, blank=True)
    tag_name = models.ManyToManyField(Tag)
    question = models.CharField(max_length = 200)

class Tag(models.Model):
    tag_name = models.CharField(max_length = 200)

and in forms.py I have:

class QuestionForm(forms.ModelForm):
    tag_name = forms.CharField(widget = forms.TextInput)
    class Meta:
        model = Question

    def clean_tag_name(self):
        data  = self.cleaned_data
        tag_name = data.get('tag_name', None)
        if tag_name is not None:
            for tags in tag_name.split(','):
                try:
                    tag = Tag.objects.get(tag_name=tags)
                except Tag.DoesNotExist:
                    tag = Tag.objects.create(tag_name = tags)

        return tag_name

    def save(self, commit=True):
        ints = super(QuestionForm, self).save(commit=commit)
        tags = self.cleaned_data.get('tag_name', None)
        if tags is not None:
            for tag in tags.split(","):
                tag = QuestionForm.objects.create(name=tag_name)
                ints.tag_name.add(tag)
                ints.save()
        return ints

Upvotes: 2

Views: 1347

Answers (1)

mbrochh
mbrochh

Reputation: 1011

Your code snippet has a few flaws:

You can't do QuestionForm.objects.create(name=tag_name) because QuestionForm is not a model and has no objects attribute.

You probably wanted to write Question.objects.create(name=tag_name) but that wouldn't work as well because Question has no field name and you don't have a variable called tag_name at that point.

Furthermore, in your clean() method you make sure that the tags the user had entered exist in the database, but in your save() method you are trying to add the tag names (as in: the strings) and not the tag objects to the M2M field. You can't do that. The .add() method of the M2M field expects an instance of the Tag model. This means, in your .save() method, you have to split your tag strings again, then fetch the Tag objects from the database and add those instances to the Question instance you just created.

Try this instead:

First change the class Meta:

class Meta:
    model = Question
    fields = ['topic', 'question']

This makes sure that the form doesn't try to save the tag_name field. This is important, otherwise the super() call below would try to add something like tag1, tag2, foobar to the M2M field, which is not possible (remmeber, you can't add strings to an M2M field, you can only add instances).

Then change the save method:

def save(self, *args, **kwargs):
    obj = super(QuestionForm, self).save(*args, **kwargs)
    tags = self.cleaned_data.get('tag_name', None)
    if tags:
        for tag in tags.split(","):
            tag = Tag.objects.get(tag_name=tag)
            obj.tag_name.add(tag)
    return obj

Upvotes: 3

Related Questions