18

Working with Django 1.11 and a postgreSQL Database (just switched from sqlite and didn't have this problem before)

So I have 3 models:

models.py

class Person(models.Model):
    is_parent = models.BooleanField()

class VideoGamePurchase(models.Model):
    bought_by = models.ForeignKey(Person)
    after_homework = models.OneToOneField(HomeWork, OPTIONS???)

class HomeWork(models.Model):
    done_by = models.ForeignKey(Person)
    content = models.CharField(blablaba)

So the logic I'm try to implement is that if Person.is_parent is True a VideoGamePurchase instance can be created with an empty or null field for after_homework. However, if Person.is_parent is False, I want this field to be the primary key of a unique HomeWork object.

I can't find the right options to achieve this:

If I don't have primary_key=True then the makemigrations fails:

You are trying to add a non-nullable field 'id' to video_game_purchase without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

so I guess I hav to have primary_key=True. But then it seems like I can't have null=Trueor blank=True.

Is there a way to have a OneToOneField optionally empty with postgreSQL?

Is there a other/simpler way to implement this sort of logic?

Thanks for your help!

Just trying
  • 484
  • 1
  • 5
  • 15

1 Answers1

29

If you want the after_homework field to be optional, then you should use null=True and blank=True.

class VideoGamePurchase(models.Model):
    bought_by = models.ForeignKey(Person)
    after_homework = models.OneToOneField(HomeWork, null=True, blank=True)

You don't want primary_key=True for the after_homework - that would make the after_homework the primary key field of the VideoGamePurchase model, which doesn't make sense if the field is optional.

It looks like your migrations are messed up because you had primary_key=True for the after_homework field earlier. The easiest fix would be to start with a fresh database, delete the migrations for that app, then rerun makemigrations and migrate. This time, the migration will automatically create a primary key field id for the VideoGamePurchase model.

Alasdair
  • 298,606
  • 55
  • 578
  • 516