Why makemigrations in django doesn't work? - python

I wanted to insert into my database from an Excel file. So I created a model in my models.py file.
models.py
from django.db import models
class Materiau(models.Model):
designation = models.CharField(max_length=128)
norme = models.CharField(max_length=128)
temperature = models.CharField(max_length=128)
epaisseur = models.CharField(max_length=128)
symbole = models.CharField(max_length=128)
rho = models.FloatField(default=0.0)
E = models.FloatField(default=0.0)
sigy = models.FloatField(default=0.0)
Etan = models.FloatField(default=0.0)
def __str__(self):
return self.designation
Then I created a Commands file :
Path : my_app/management/commands/update_database.py
from django.core.management.base import BaseCommand
import pandas as pd
from DataMat.models import Materiau
from sqlalchemy import create_engine
class Command(BaseCommand):
def handle(self, *args, **options):
df = pd.read_excel('dataframe.xlsx')
engine = create_engine('sqlite:///db.sqlite3')
df.to_sql(Materiau._meta.db_table, if_exists='replace', con=engine, index=True)
Then when I run python manage.py update_database I can see the database being updated in my db.sqlite3 file.
But when I run the makemigrations I get no changes detected and I can't see my database in the Django admin section.
This is the error I get from Django : no such column: DataMat_materiau.id I don't understand because when I look into my database I can see an index but Django doesn't seem to recognize it.
Also in my update_database.py file, I have this message Access to a protected member _meta of a class.
Does anyone have an idea on how to fix this?

Related

How to set a default field in my class for make a migration to my sqlite db at Django Rest?

I have issues when I'm trying to execute the following code at Ubuntu terminal:
$ python manage.py makemigrations
I need to add a field called 'album' in my class named music, like that:
models.py file
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Music(models.Model):
class Meta:
db_table = 'music'
title = models.CharField(max_length=200)
seconds = models.IntegerField()
album = models.ForeignKey('Album', related_name='musics')
def __str__(self):
return self.title
class Album(models.Model):
class Meta:
db_table = 'album'
title = models.CharField(max_length=200)
band = models.ForeignKey('Band', related_name='albuns')
date = models.DateField()
serializers.py file
from rest_framework import serializers
from .models import Music, Band, Album, Member
class MusicSerializer(serializers.ModelSerializer):
class Meta:
model = Music
fields = '__all__'
class BandSerializer(serializers.ModelSerializer):
class Meta:
model = Band
fields = '__all__'
My error obtained:
(music) leonardo.oliveira#dss-skinner:~/django_music/myapi$ python manage.py makemigrations
You are trying to add a non-nullable field 'album' to music 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
What is happening here is, It is trying to add an album field in music model. According to defination of this field
album = models.ForeignKey('Album', related_name='musics')
it is a non-nullable field. instant fix would be
album = models.ForeignKey('Album', related_name='musics', null=True)
but if you want to add a default album for this field you can add a default by doing something like this.
album = models.ForeignKey('Album', related_name='musics', default=Album.objects.first())
but for this to work you should have atleast one album present in DB.
After doing these changes you run
python manage.py migrate

I changed ManyToManyField relationship in ForeignKey, but now don't work

I'm new to Django and I have this problem: I want to create a simple web site where I display and work through the views objects Album and Artist. I changed the relationship
class Album(models.Model):
...
songs_of_album = models.ManyToManyField('Song')
class Song(models.Model):
name = models.CharField(max_length=150)
in my current models.py file
from django.db import models
from django.utils import timezone
class Album(models.Model):
name = models.CharField(max_length=150,default='')
artist = models.CharField(max_length=150,null=False,blank=False)
year = models.IntegerField(default=timezone.now().year)
genre = models.ForeignKey('Genre',blank=False)
vote = models.IntegerField(blank=True,null=True)
def __str__(self):
return self.name
class Song(models.Model):
name = models.CharField(max_length=150,null=False,blank=False)
album_name = models.ForeignKey('Album')
artist = models.ForeignKey('Artist')
def __str__(self):
return self.name
class Artist(models.Model):
name = models.CharField(max_length=150,primary_key=True)
def __str__(self):
return self.name
class Genre(models.Model):
name = models.CharField(max_length=150,primary_key=True)
def __str__(self):
return self.name
I want to know two things:
if my models.py is written right and the relationship that exists between the class and Album Artist
Now when I run the command python manage.py makemigrations gives me this error You are trying to add a non-nullable field 'id' to album 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)
2) Quit, and let me add a default in models.py
Select an option:
I have read many posts similar but they are not able to find the solution.
I hope you can help me. Thank you
You changed m2m relationship to one2many, all is ok, but you need change your related database tables and you must migrate your db to new style, if you have any data on db set null=True for album_name attribute of Song class, and if your db is empty, delete all file in migrations folder of your app except __init__.py file, and then run two below commands:
python manage.py makemigrations
And then:
python manage.py migrate

Foreign key constraint error on Django app

I'm trying to have this third class noticeTime be constrained to the foreign key email. I am using the same syntax that worked for the 2nd class location, but when I use it on noticeTime it throws an error:
Exception Value: no such column: setupNotifications_noticetime.email_id
Here is the code:
from django.db import models
# Create your models here.
from django.db import models
class email(models.Model):
email = models.CharField(max_length=200)
def __unicode__(self):
return self.email`
class location(models.Model):
email = models.ForeignKey(email)
zip_code = models.CharField(max_length=5)
def __unicode__(self):
return self.zip_code
class noticeTime(models.Model):
email = models.ForeignKey(email)
time = models.CharField(max_length=200)
def __unicode__(self):
return self.time
here is admin.py:
from django.contrib import admin
# Register your models here.
from setupNotifications.models import email
from setupNotifications.models import location
from setupNotifications.models import noticeTime
admin.site.register(email)
admin.site.register(location)
admin.site.register(noticeTime)
I'm using the sqlite database
Perhaps your problem is that you ran syncdb, assuming that it would alter the table to match your model change. Unfortunately, it does not do that. There are some separate tools available, such as South, which can help with database migrations.

Model has either not been installed or is abstract

When I try to migrate my code I get this error.
Here are my code and classes:
from django.db import models
from core.models import Event
class TicketType(models.Model):
name = models.CharField(max_length=45)
price = models.DecimalField(max_length=2, decimal_places=2, max_digits=2)
type = models.CharField(max_length=45)
amount = models.IntegerField()
event = models.ForeignKey(Event)
class Meta:
app_label = "core"
import datetime
from django.core.serializers import json
from django.db import models
from core.models import User
class Event(models.Model):
page_attribute = models.TextField()
name = models.TextField(max_length=128 , default="New Event")
description = models.TextField(default="")
type = models.TextField(max_length=16)
age_limit = models.IntegerField(default=0)
end_date = models.DateTimeField(default=datetime.datetime.now())
start_date = models.DateTimeField(default=datetime.datetime.now())
is_active = models.BooleanField(default=False)
user = models.ForeignKey(User)
ticket_type=models.ForeignKey('core.models.ticket_type.TicketType')
class Meta:
app_label = "core"
Here is the error I get:
CommandError: One or more models did not validate:
core.event: 'ticket_type' has a relation with model core.models.ticket_type.TicketType,
which has either not been installed or is abstract.
You're unnecessarily confusing yourself by having these in separate files within the same app.
But your issue is caused by the way you're referenced the target model. You don't use the full module path to the model: you just use 'app_name.ModelName'. So in your case it should be:
ticket_type=models.ForeignKey('core.TicketType')
Another issue can be when using multiple models in separate files missing statement like:
class Meta:
app_label = 'core_backend'
You can also get this error if there a bug in your models file that prevents it from loading properly. For example, in models.py
from third_party_module_i_havent_installed import some_method
I hit this error when I didn't put a third-party app in my INSTALLED_APPS setting yet.

Is there an order in which models are generated into database?

In my project I need to change the location where files are being uploaded. This is done using a FileSystemStorage. The path were the files are uploaded should be easy to configure, for example using the Django Admin.
from django.core.files.storage import FileSystemStorage
from django.db import models
class Setting(models.Model):
entry = models.CharField(primary_key=True, db_column="entry", max_length=50)
value = models.CharField(db_column="value", max_length=250, blank=True, null=True)
def __unicode__(self):
return "%s" %(self.entry)
class Meta:
db_table = 'settings'
verbose_name = 'Setting'
verbose_name_plural = 'Settings'
fs = FileSystemStorage(location=Setting.objects.get(entry__exact='upload_path').value)
def generate_filename(instance, filename):
...
class FileImport(models.Model):
data_file = models.FileField(_('Data file'), upload_to=generate_filename, storage=fs)
I receive this error:
django.db.utils.DatabaseError:
relation "settings" does not exist
LINE 1: ...ELECT "settings"."entry", "settings"."value" FROM "settings"...
for the line where FileSystemStorage is being created. Is there a way of telling Django to create table settings(for Setting objects) first and then fill this table with some fixtures?
That won't solve your problem, since the Settings table still won't be populated. Move it into a class attribute that gets initialized the first time it's instantiated.

Categories