Django thinks I have an id field when I do not - django

I have created the following model:
class World(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
setting = models.CharField(max_length=200)
creation_date = models.DateTimeField('date created')
when I run manage.py makemigrations I get the following error:
You are trying to add a non-nullable field 'id' to world 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
Why does Django think I have an id field, and how do I get rid of this error?

I had previously set an ID field in my World model, this was confusing something as I had deleted it, I have added the line:
id = models.AutoField(primary_key=True)
When i ran makemitigrations again it asked me if I had renamed the ID field to this new one and I clicked yes and this sorted it out.
My model is now:
class World(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default='')
name = models.CharField(max_length=200)
setting = models.CharField(max_length=200)
creation_date = models.DateTimeField('date created')

Related

Django, Sqlalchemy: Cannot drop table ganalytics_article because other objects depend on it

I have this models in my Django ganalytics app:
class Article(models.Model):
id = models.IntegerField(unique=True, primary_key=True)
article_title = models.CharField(max_length=250)
article_url = models.URLField(max_length=250)
article_pub_date = models.DateField()
class Company(models.Model):
company_name = models.CharField(max_length=250)
class Author(models.Model):
author_sf_id = models.CharField(max_length=20, null=True)
author_name = models.CharField(max_length=250)
class AuthorArticleCompany(models.Model):
author = models.ForeignKey(Author,
to_field="id",
on_delete=models.CASCADE,
related_name='authorarticle_author_id')
company = models.ForeignKey(Company,
to_field="id",
on_delete=models.CASCADE,
related_name='authorarticle_company_id')
article = models.ForeignKey(Article,
to_field="id",
on_delete=models.CASCADE,
related_name='authorarticle_article_id')
class Ganalytics(models.Model):
article = models.ForeignKey(Article,
on_delete=models.CASCADE,
related_name='ganalytics_author_id')
totalview = models.IntegerField()
totalinteractions = models.IntegerField()
class Unsubscribers(models.Model):
email = models.EmailField()
reasonwhy = models.CharField(max_length=90)
I am running pandas to_sql to upload the database:
authorarticlecompanydf.to_sql("ganalytics_authorarticlecompany", con=engine, if_exists="append", index=False)
articledf.to_sql("ganalytics_article",con=engine,if_exists="replace",index=False)
company_name.to_sql("ganalytics_company",con=engine,if_exists="replace",index=False)
authordf.to_sql("ganalytics_author", con=engine,if_exists="replace", index=False)
I am getting this error message:
DETAIL: constraint ganalytics_ganalytic_article_id_d37f2464_fk_ganalytic on table ganalytics_ganalytics depends on table ganalytics_article
constraint ganalytics_authorart_article_id_7f4ff374_fk_ganalytic on table ganalytics_authorarticlecompany depends on table ganalytics_article
HINT: Use DROP ... CASCADE to drop the dependent objects too.
[SQL:
DROP TABLE ganalytics_article]
I have tried to change the on_delete field to different values but it wont help.
What am I doing wrong?
What is the command you are running to get the error? The bottom line is Ganalytics depends on Article via the FK between them. By dropping Article first you are breaking that dependency. You either need to DROP Ganalytics first and then Article or follow the hint DROP ... CASCADE. Though be aware that will DROP Ganalytics also.
UPDATE
Another option would be to drop the FK between the two tables. Then you would not have the dependency issue.

Django ForeignKey value does not have corresponding value

I'm working on the Django section of CS50 around the 30min mark on the video with the modes 'ForeignKey' section.
When i run the make migration i get the error.
You are trying to add a non-nullable field 'agent' to product 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
Select an option: 2
if I set the default as a string value i get the error saying it was expecting an id.
If i set it as 1 then i get the following.
The row in table 'clutter_product' with primary key '1' has an invalid foreign key: clutter_product.agent_id contains a value '1' that does not have a corresponding value in clutter_supplier.id.
class Supplier(models.Model):
company = models.CharField(max_length=64)
contact = models.CharField(max_length=64)
email = models.CharField(max_length=128, blank = True)
def __str__(self):
return f"{self.id} {self.company} {self.contact} {self.email}"
class Product(models.Model):
name = models.CharField(max_length=64)
sku = models.CharField(max_length=64, blank = True)
unit_cost = models.IntegerField()
rrp = models.IntegerField()
average_fee = models.IntegerField()
shipping_fee = models.IntegerField()
agent = models.ForeignKey(Supplier, default=1, on_delete=models.CASCADE, related_name="suppliers")
I would suggest to try these steps:
First, delete the migration file which is causing this problem.
Second change the model like this:
class Product(models.Model):
# rest of the fields
agent = models.ForeignKey(Supplier, null=True, default=None, on_delete=models.CASCADE, related_name="suppliers")
Third run makemigrations and migrate.
Fourth create a instance of supplier using supplier = Supplier.objects.create(company="ABC", contact="contact", email="a#b.c", pk=1)
Fifth(optional) Update the existing Product to haven a supplier-Product.objects.update(agent=supplier).
Sixth, if you want to constrain Products to be created with an agent, then remove null=True, default=None from agent field in Product model. Then run makemigrations and migrate.

Django: How can I add/delete fields in sqlite3 database?

I've started learning Django from a YouTube course.
In the models.py file, there are two classes.
class Album(models.Model):
artist = models.CharField(max_length = 250)
album_title = models.CharField(max_length = 250)
album_logo = models.CharField(max_length = 1000)
def __str__(self):
return self.album_title + ' - ' + self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
genre = models.CharField(max_length=250)
def __str__(self):
return self.song_title
I added the genre in the Song after the migration. That's why I'm having problem while adding data.
In the interactive shell, if I try to save() , it shows there's no 'genre' field. If I try to migrate again, it shows something like this:
You are trying to add a non-nullable field 'genre' to song 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 Select an option:
What's the proper way of adding or deleting fields?
add default="" to genere field
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
genre = models.CharField(max_length=250, default="")
def __str__(self):
return self.song_title
As the error message shows, you add a field genre to Song model without adding default="" nor null=True parameters to it. When you migrate it, django don't know how to deal with the old data that has been inserted into the database without genere field. So you should set them to null with null=True or other default value with default="".
You can also just keep your code. But when you use the migrate command, you should tell django that you will give a default value like the django recommanded:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
press 1 and enter key. input "" and then django will set all the old data genre="".

django get associated data one to one field

I'm working in Django 2.0
I have a model Note to save note and two another models to add color labels to the note.
class Note(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=250, blank=True, default='Untitled')
content = models.TextField(blank=True)
class ColorLabels(models.Model):
title = models.CharField(max_length=100, unique=True)
value = models.CharField(max_length=100)
default = models.BooleanField(default=False)
class NoteLabel(models.Model):
note = models.OneToOneField(Note, on_delete=models.CASCADE)
color_label = models.OneToOneField(ColorLabels, on_delete=models.CASCADE)
with the object of Note
note = Note.objects.get(pk=1)
I want to access associated ColorLabels's title and value fields or the NoteLabel object.
since they are one to one field. I tried doing
note.note_label
note.NoteLabel
note.note_label_set
But all returns error as
AttributeError: 'Note' object has no attribute 'note_label_set'
Unless you define related_name in your OneToOneField, Django will use lowercased model name to access related object. So, note.notelabel should work.

Django postions: adding PositionField breaking migration

I have already tables for Vehicle and Car, Using this django-positions for postioning my items of the tables. For that i have added the positon field in both the models.
class Vehicle(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
position = PositionField()
And
class Car(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
vehicle = models.ForeignKey(Vehicle, related_name="vehicle")
position = PositionField()
makemigrations ran fine but while migrate getting following error. using postgreSQL
django.db.utils.IntegrityError: check constraint "myapp_vehicle_position_check" is violated by some row
It turns out that during the migration the SQL code checks for the value of the PositionField to be greater than or equal to 0. The default being -1 for automatic ordering the migration fails.
I haven't digged any more but as a turnaround changing the default value to something equal or above zero allow for the migration to be successful.
class Vehicle(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True)
position = PositionField(default=99)
Hope this helps.