0

I have two models, Article and ArticlePost. ArticlePost references Article as a foreign key and is in a separate application to Article:

====app1/models.py:======
class Article(models.Model):

     name = models.CharField(max_length=200, primary_key=True)

====app2/models.py======
class ArticlePost(models.Model):

    article = models.ForeignKey(Article, null=False, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)
    comment = models.TextField(blank=True)

I have run python manage makemigrations which gives the following:

operations = [
migrations.CreateModel(
    name='ArticlePost',
    fields=[
        ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)),
        ('created_at', models.DateTimeField(auto_now_add=True)),
        ('comment', models.TextField(blank=True)),
        ('article', models.ForeignKey(to='app2.Article')),
    ],
),
]

However when I run python manage migrate I get:

django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "article"

What is strange is that I have another model in app1 which also references article with a foreign key which works perfectly. However in this case it would appear that Django does not know which field is the primary key for Article. The only difference is that ArticlePost is in a different application from Article. I am running Django 1.10. Does anyone have any idea what is causing this and how it might be fixed?

Alternatively if it is just a key issue maybe a solution is to remove the primary_key on Article and use the Django default id instead. In this case, how is best to do this while maintaining the Foreign Key references from other models to Article within app1?

mohevi
  • 63
  • 2
  • 8
  • This doesn't answer your question, but you can remove `null=False` on your model field. By default, `null=False`. You only need to add a `null` value if you are setting it to `True`. – jape Aug 04 '16 at 14:02

2 Answers2

0

Okay so what you tried to do is absolutely correct. But the problem here is with Django.

When you are setting name as primary_key then according to the official documentation -> https://docs.djangoproject.com/ja/1.9/ref/models/fields/#django.db.models.Field.unique

primary_key=True implies null=False and unique=True.

So technically, you do have a unique field in your Article model, but after going through few other posts on Stackoverflow,

see this as a reference (go through the comments too) -> Primary key and unique key in django

it seems that there some issue with the primary_key=true. It seems that django only considers it as a primary key but not as unique

So when you use a primary_key=true for name, then Django doesn't creates it own unique auto-incrementing ids for objects. Hence now you don't have any unique id for an object in the model Article due to which you get the error you are getting.

So, simply remove the primary_key=true and let Django use its own auto incrementing unique ids and you should not get that error.

Community
  • 1
  • 1
Ankush Raghuvanshi
  • 1,392
  • 11
  • 17
  • Thanks for that Ankush, it's good to know what's going on. When I try that I get `You are trying to add a non-nullable field 'id' to Article without a default; we can't do that (the database needs something to populate existing rows)`. What should that default be? It seems Django doesn't realise it needs to auto-populate existing records with the new id. Secondly, assuming I could give a value, what will happen to existing models with a Foreign key to `Article`? Will they be maintained? – mohevi Aug 04 '16 at 15:21
  • Yea, you are right that Django doesn't realizes that it needs to autopopulate, as there it only adds that unique id when a new object is added to that Model. So now, no new is being added, hence it doesn't populates the already existing one. I guess you'll have to add them by yourself using `python manage.py shell` and then running a simple loop to do so. Or else, if you can backup your data, delete the current one and again add that data back. That way it will create ids for the newly created ones. Also delete all the migrations before adding the new data and do fresh migrations. – Ankush Raghuvanshi Aug 04 '16 at 15:35
  • And i'm not sure about your second question, but i feel if Django was not allowing you to keep that foreign key in the first place, then no foreign key would be saved initially, right? So the scenario of maintaining doesn't comes into picture. Does it? – Ankush Raghuvanshi Aug 04 '16 at 15:38
  • I think you already have data in database and now you are trying to add relation on the table so may be when your declaring it as primary key, it's having some data contains null values or may be that column doesn't have all unique values. Still if you are trying to do `unique=True`it will gives you error. – Piyush S. Wanare Nov 15 '16 at 08:55
-1

@mohevi, check if you are using MongoDb as database, as mongodb do not supports Foreign key feature. these are supported normally in RDBMS like postgresql, MySQL etc