Using get_or_create() for foreign keys in ModelForm

In my UserID model are a couple of foreign keys. In my UserIDForm I changed the widget for these fields to TextInput widgets and now I am trying to use that input and the get_or_create() method to either get or create the correspoding objects.

class Group(models.Model):
    group_name = models.CharField(max_length=30, verbose_name='Gruppe')


class Room(models.Model):
    room_name = models.CharField(max_length=30, verbose_name='Raum')


class UserID(models.Model):
    userid_name = models.CharField(max_length=30, verbose_name='UID')
    room = models.ForeignKey(Room, on_delete=models.SET_NULL, null=True)
    group = models.ForeignKey(Group, on_delete=models.SET_NULL, null=True)
    location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True)
class UserIDForm(ModelForm):
    class Meta:
        model = UserID
        fields = ('userid_name', 'group', 'room', 'location',)
        labels = {
            'group': 'Gruppe',
            'room': 'Raum',
            'location': 'Standort',
        }
        widgets = {
            'group': forms.TextInput(),
            'room': forms.TextInput(),
        }

    def clean(self):
        group_data = self.cleaned_data.pop('group')
        group, created = Group.objects.get_or_create(group_name=group_data)
        self.cleaned_data.update({'group': group})

        room_data = self.cleaned_data.pop('room')
        room, created = Room.objects.get_or_create(room_name=room_data)
        self.cleaned_data.update({'room': room})

But when I submit the form I get the following error:

    group_data = self.cleaned_data.pop('group')
KeyError: 'group'

I’m new to django and programming in general so I might be missing something very obvious but any help would be highly appreciated.

There are a couple things wrong with what you’re trying to do here - and I’m not sure which would be causing this specific issue.

Your group field in the UserID model is not a character string - it’s a ForeignKey to another model. However, you’re trying to submit a name for that field - it’s a data-mismatch which is likely to fail the cleaning process for that field.

As it appears that you want to person to be able to either enter the name of an existing group or to enter a new name to use to create the group, you need to handle this a bit differently.

You do not want to use the group field in your form. You would want to define a separate field for the entry of that group name. In your view, you would then use the get_or_create call to either create the new group or retrieve the existing group, and then assign that to the group field of your model.

Having said all that, this type of processing is generally considered a bad practice. Anyone making a typo is going to create a new-and-possibly-undesired group. It’s a lot safer and more robust to provide the selection field for existing groups along with some separate mechanism to allow for new groups to be created.

I see, thank you for the quick help!