Reputation: 818
I am developing a dictionary application using Django. I am having trouble successfully creating a form using Django's ModelForm
class that allows users to submit new definitions to BOTH existing AND new dictionary headwords.
My models.py:
class Headword(models.Model):
headword = models.CharField(max_length=64, unique=True)
class Definition(models.Model):
definition = models.CharField(max_length=64)
headword = models.ForeignKey(Headword, related_name="definitions_headword")
My forms.py:
class DefinitionForm(forms.ModelForm):
class Meta:
model = Definition
fields = ["headword", "definition"]
My HTML form:
<form action="{% url 'dictionary:define' %}" method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Define</button>
</form>
The result of all is a form with:
With the above code, therefore, the user is ONLY allowed to add definitions to headwords that already exist.
As I said, I would like to change that and have this form such that users are able to submit definitions to BOTH existing headwords (the ones in the dropdown menu), AND new ones (ones that the user can just type in). This means I wouldn't want a dropdown menu at all in the form, but just two unconstrained text input fields and a submit button.
How could I achieve that?
PS: I tried to override the dropdown menu to be a text input field using the widgets
dictionary in the DefinitionForm
class. This, however, results in an error message appearing above the headword form field when I try to submit the form saying:
Select a valid choice. That choice is not one of the available choices.
Upvotes: 0
Views: 695
Reputation: 490
Since you have a ForeignKey type field, it would automatically change the widget to a dropdown, so I would keep that change in the widgets dictionary.
It looks like you are looking for a many-to-many relation. Take a look at the Django Docs and also look for formsets and inline formsets.
But if you mean to create new Headwords at the same time you are creating definitions, that part is a little tricky.
Just to test, try change the field to a regular text input to submit headword data as CSV (or something else easy to parse) and parse it. for each result if the headword does not exist, you create it in the DB and then you associate the definition. If it does you just associate it.
If it works, the next step is to find a widget that allows you follow the same way of thinking - I can't think of any, sorry :/
Upvotes: 1