I don't seem to understand this error or how to fix it. There's something I don't understand about django models.
Consider what happens when I try to perform get_or_create
on the Keyword
model. Here's the model, alongside some code I write in shell.
@python_2_unicode_compatible
class Keyword(models.Model):
word = models.CharField(max_length=200)
statement = models.ManyToManyField(Statement)
def __str__(self):
return self.word
>>> from gtr_site.models import *
>>> a = Statement()
>>> Keyword.objects.get_or_create(word="Testkeyword", statement=a)
Traceback (most recent call last): ...
ValueError: "<Keyword: Testkeyword>" needs to have a value for field "keyword" before this many-to-many relationship can be used.
But if you simply write Keyword.objects.get_or_create(word="TestKeyWord")
(so if you exclude the statement instance entirely), then the error disappears.
I really don't understand how this error can be occurring because... Neither the Statement
model nor the Keyword
model actually have a field called "keyword."
However, the Statement
model does have a lot of components. Here's the code for it.
@python_2_unicode_compatible
class Statement(models.Model):
statement_id = models.CharField(max_length=200)
title = models.CharField(max_length=200)
issue_date = models.DateField("Issue-Date")
author = models.ForeignKey(Person)
released_by = models.ForeignKey(Organization)
keywords = models.ManyToManyField('KeywordInContext')
solokeywords = models.ManyToManyField('Keyword', related_name='statement_keywords')
There's three more choice fields in the model that I chose to exclude for the sake of clarity.
There's only one field in the Statements
model that actually does have a field called keyword. The field "keywords" which creates a ManyToMany relationship with KeywordInContext
This model is as follows:
@python_2_unicode_compatible
class KeywordInContext(models.Model):
keyword = models.ForeignKey(Keyword)
contexts = models.ManyToManyField(Keyword, related_name='keyword_context')
def __str__(self):
return self.keyword.word + ' (' + ', '.join(c.word for c in self.contexts.all()) + ')'
Important to note is that the field keyword makes a ForeignKey to a Keyword
object.
So... I still don't understand how this is happening. When I am trying to create new Keyword that has both of its word
and statement
field's as parameters, I don't understand why a field from KeyInContext even becomes relevant. With respect to that, how do I create a Keyword
object with both of its word
and statement
parameters specified?
The error is trying to tell you that you need to save the Keyword object before you can link to it via a many-to-many. You will also need to save the Statement; this is because an m2m relationship involves a linking table, so both sides need IDs before you can link them. In other words, you can't assign an m2m field in the create
call.
As to why you get that particular message, I guess you have an old version of the models in memory where you defined the primary key field as keyword
.