4

I am building a service that makes short URLs. I have the models:

from django.db import models

class ShortURL(models.Model):
    url = models.CharField(max_length = 50)

class LongURL(models.Model):
    name = models.CharField(max_length = 100, null=True)
    url_to_short = models.ForeignKey(ShortURL)

I have already run the command: python manage.py migrate If I open the interpreter, using python manage.py shell and run this code:

>>> from appshort.models import LongURL
>>> a = LongURL(name = 'hello_long_link')
>>> a.save()

then I get the error:

django.db.utils.IntegrityError: NOT NULL constraint failed: appshort_longurl.url_to_short_id

What did I do wrong?

thumbtackthief
  • 6,093
  • 10
  • 41
  • 87
Q-bart
  • 1,503
  • 4
  • 22
  • 41
  • 1
    `url_to_short` FK field is required on your model but you forgot to fill it. – dani herrera May 28 '15 at 12:24
  • 2
    You create a `LongURL` without giving it a `ShortURL`, which is an error. If that's a valid case, make the `ShortURL` field optional as described here: https://stackoverflow.com/questions/6619984/can-i-make-the-foreign-key-field-optional-in-django-model – l4mpi May 28 '15 at 12:25

2 Answers2

6
class LongURL(models.Model):
    name = models.CharField(max_length = 100, null=True)
    url_to_short = models.ForeignKey(ShortURL)

The way you have set it up, the url_to_short foreign key is not optional. So when you try to save:

>>> a = LongURL(name = 'hello_long_link')
>>> a.save()

Django is trying to tell you that you didn't provide the url_to_short relation on your a model instance.

You'll need to either

  • Provide the ShortURL relation when you create the LongURL instance
  • Make the url_to_short relation optional with null=True, blank=True.
wim
  • 338,267
  • 99
  • 616
  • 750
  • this is especially confusing since I have another example where `default=None` worked in the same situation, but now it seems that `null=True, blank=True` is required (?). – szeitlin Jul 09 '15 at 19:59
0

While creating an entry for LongURL you must create an object of ShortURL or filter out already existing (because ForeignKey field cannot be left blank). Additionally, you say that sometimes you have been able to achieve the desired behaviour. This can be so because at those places you would have got an object of ShortURL which is not null. However, the error in the discussion arises, when you try to send a null object during the creation of LongURL. For example:

...
short_url_obj = ShortURL.objects.filter(...).first()
# you have to ensure that this above query is not null
try: 
    new_long_url = LongURL(url_to_short=short_url_obj, name="some_name")
    new_long_url.save()

except:
    # if the short_url_obj is null
    print("The short_url_obj was null, cannot save to database")

...

One can also use if-else block instead, but I would not advice that.

Amiay Narayan
  • 461
  • 9
  • 8