I do not have a deep understanding of Django, anyway not deep enough to overcome a problem that turns up in my application.
In models.py I have a.o. the following definitions:
class Relatiedata(models.Model):
...
getuigen = models.TextField(blank=True, null=True)
...
class Meta:
db_table = 'relatiedata'
Relatiedata.objects = Relatiedata.objects.using('genealogie')
So in the database genealogie, which is not the default database, I have a table relatiedata with a column getuigen that has to contain a text string without a limitation on the length.
Further, I have a user form for mutating records of this table. As usual, the form is populated from a Relatiedata.object and the returned form results in another Relatiedata.object which is saved, thereby updating the database. This works (almost) perfect.
The problem is that in my form it turns out to be impossible to enter a string of length above 600 in the textarea for getuigen. Longer strings are simply cut off. There seems to be sort of a form validation for the length of that field, despite the fact that there is no such limit in the models, nor in the database, nor in the migration files.
This value of 600 comes from earlier, abandoned, implementations of the model, where originally I had a CharField with max_length 600 instead of a TextField.
All remarks are highly welcome.
EDIT
Some additional information. As it is now, the models were created from the already existing database, which is a simple sqlite database with some tables, no relations between the tables. The table relatiedata is a simple table with some textual columns, a little bit too large to show here. Makemigrations and migrate were of course used after the models were constructed, and at the moment makemigrations does not find anything to migrate.
Even worse: when I change the definition:
getuigen = models.CharField(max_length=2000, blank=True, null=True),
makemigrations shows this change and migrate solves it, but it is still impossible to use a string of more than 600 characters in the form. With less, it is OK.
Finally, I can change the value of the field getuigen to strings with more than 600 characters by using SQL. Having done that, in my application the long string turns up correctly in all output where it should be, even in my mutation form. But in the mutation form it cannot be edited because it is too long.
Make migrations and migrate again
python manage.py makemigrations specify_app_name
then
python manage.py migrate specify_app_name
Related
Hi, I'm trying to alter my current django project schema, the data migration tool is south. django version is 1.6.9.
It is a existing database so I don't want to mess up with my historical data.
What I'm trying to alter is making a blank=true field non-empty(blank=false)
here is my model class:
class Post(DraftableModel, EditTrackingModel):
title = models.CharField(max_length=120,
verbose_name='headline')
description = models.CharField(max_length=260,
blank=True,
verbose_name='lead-in',
help_text="260 character limit")
/*rest of the code*/
I want change the description from models.CharField(blank=True) to models.CharField(blank=False), which is the default blank value
considering the existence of my database, some of my old Post model do have empty description.
After my migration and change of database schema, will my database be corrupted?
When you try to migrate, django will warn you about those empty fields. so you have few options.
You can add a default value in your model like default="Some Default Value" and django will chose that default value for all empty fields on migration.
You can just send the migrate request and on the terminal, django will ask you to add an one-off value to be added to all the empty fields.
Also you can edit the migrate files and add different values for those empty fields based on conditions you have in mind.
You can write a function to check for all the empty fields for exiting rows and add some data based on some conditions.
Also i highly recommend to make a backup first. Doesn't matter how small the changes are or how good you are in coding.
I'm using django-modeltranslation to translate models in my app. I've a model wich I've sync with the db with migrate command. Also I've a lot of records for that model.
class Home(models.Model):
description = models.TextField()
Of course, at this point, I can retrieve description field from db
h = Home.objects.first()
h.description # --> "This home is near to..."
Now, I want to become the description field translatable using django-modeltranslation. I've follow de guide, I've registered the model for translation in the translation.py file, Finally I've executed makemigrations and migrate commands. This added to my db, in the home table, the fields description_en and description_es, as my availabe languajes are en and es, the former is the default.
At this point i need to populate the description_en field wich is the default for any query, I tried
Home.objects.all().update(description_en=F('description'))
but it doesn't work because when it tries to access to the description field it in fact is trying to access to description_en, and it is empty:
h = Home.objects.first()
h.description # --> '' Empty?!!!
I've check if the data still in the db and they are!
My question is: if description data still in db, and h.description retrieve me in fact h.description_en, How can I populate description_en for all data in description field?
reading this django-modelstranslation fallback original field value, I realized of existence of management command that is shipped with modeltranslation and it populate the default lang: python manage.py update_translation_fields
I'm reading this tutorial to lear the basics of django and I'm facing a problem I can't solve.
I'm at this page http://www.tangowithdjango.com/book17/chapters/models_templates.html at the sluglify function approach.
In the tutorial the author says we have to create a new line in our category model for th slugfield. I folow strictly all the steps just as I show here:
from django.db import models
from django.template.defaultfilters import slugify
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
likes = models.IntegerField(default=0)
views = models.IntegerField(default=0)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=128)
url = models.URLField()
views = models.IntegerField(default=0)
def __unicode__(self):
return self.title
When I run the "makemgiration" command everything works as expected: I choose the first option and provide ‘’ . BUT when I run "migrate" I get:
django.db.utils.Integrity error: Slug column is not unique
What is going on here? I've repeated several times the migrations and tried other default codes but with the same ending. I can't figure out what im doing wrong. They only thing left is that i'm giving something else instead of ‘’ (Firstly I thoughtthey were '' or ").
Thankyou for your time and help!
Delete db.sqlite3 and re run
python manage.py syncdb
Then perform the migrations
python manage.py makemigrations rango
python manage.py migrate
and re run your population script. This is a downside of Django that whenever you change models.py the db must be recreated.
I am also going through the tutorial and I was having the same issue a couple days ago.
I believe the problem is that you are trying to add a new field (slug) and have it be unique for each of the elements in your table but if I'm not mistaken you already have some data in your table for which that value does not exist and therefore the value that this field would get for those rows is not unique, hence the "django.db.utils.Integrity error: Slug column is not unique".
What I did was simply to delete the data in the table (because it was only a couple of fields, so no big deal) and THEN perform the addition of the field to the model. After doing that, you can put the data back in the table (if you're following the tutorial you should have a script for automated table population so you just run that script and you're golden). Once you have done that, all the rows in the table should have a unique slug field (since it is automatically generated based on the category name) and that solves the problem.
Note that if your table is very large, this may not be a very good solution because of the deletion of data so perhaps there is a better way, like adding that field to the model without it being unique, then running a script that sets the slug field for every row to an unique value and then setting the model's field as unique but I'm not very knowledgeable on SQL and the first solution worked just fine for me so it should work for you as well.
try deleting the sqlite3.db file from the project's directory. i was stuck on a similar problem and that really works..also even if you modify your population script, you have to delete and the recreate the db file to see the changes made....
I'm deploying my django app with Dotcloud.
I use Postgres as DB.
I had a new model to my app, and I wanted to flush and syncdb the db. Everything works find when I do it. My new model, named 'Competition' appears in my admin.
The problem is that an other model, Match, has a ForeignKey with the model Competition. And when I go to 'Matchs' in my admin, I get this error:
DatabaseError at /admin/myproject/match/
column myproject_match.competition_id does not exist
LINE 1: ...team_challenger_id", "sportdub_match"."sport_id", "sportdub_...
Any idea on why the syncdb didn't make it work find?
Thank you for your help.
EDIT: My two models
class Competition(models.Model):
name = models.CharField(max_length=256)
comp_pic = models.ImageField(upload_to="comp_pics/")
def __unicode__(self):
return self.name
class Match(models.Model):
team_host = models.ForeignKey(Team, related_name='host_matches')
team_challenger = models.ForeignKey(Team, related_name= 'challenger_matches')
sport = models.ForeignKey(Sport)
competition = models.ForeignKey(Competition)
manage.py syncdb will only create missing tables. If a table already exists, but with an invalid definition, it will not be updated. This is very probably the problem that you are experiencing.
There are at least three ways to solve the problem.
The easy way: use manage.py reset to effectively drop+recreate all the tables. Easy, but of course you will lose the data.
The lazy way: install django_extensions and use manage.py sqldiff. It will show you the difference between the current structure of the database, and the expected structure. sqldiff will nicely show you SQL statements which can update the existing database to conform with your models. You can then execute those statements in a SQL shell.
The clean way: use a migrations framework like south to handle database schema updates. Of course, if you are early in the development, this is overkill (you do not want to write database migrations each time you add/change/remove a field while you're doing local development!) but if your project will have a longer life span, I definitely recommend checking out south.
I am using South to change a ForeignKey TO ManyToManyField in one of the models in Django but it is not working out as expected.
# Original Schema
class Item(models.Model):
category = models.ForeignKey(Category, default=default_category)
To be changed to
# Original Schema
class Item(models.Model):
category = models.ManyToManyField(Category, default=default_category)
So after commenting out the ForeignKey line in the model I do,
python manage.py schemamigration affected_model --auto
? The field 'Item.category' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception.
? Please select a choice:
I am confused by this because 1. I have specified a default value which is "default_category" and 2. I am not removing any field I am just changing it to ManyToManyField. My question is how to go ahead in this case? Is there any other trick to make this conversion using South?
BTW I am using South 0.7 and Django 1.1.1
Thanks for the help.
In fact you are removing the field. Foreignkeys are represented by a column in your database that in that case would be named category_id. ManyToMany relationships are represented by a "through" table. With django you can either specif the through table or have one generated for you automatically.
This is a very nontrivial migration and you will need to hand code it. It will require a bit of understanding what the underlying database representation of your model is.
You will require 3 migrations to cleanly do this. First create a schemamigration with a dummy manytomany relationship to hold your data.
Then create a datamigration to copy the foreignkey relationships to your dummy manytomany
Finally create schemamigration to delete the foreignkey and rename the dummy manytomany table.
Steps 2 and 3 will both require you to manually write the migrations. I should emphasize this is a very nontrivial style of migration. However, it's entirely doable you just have to really understand what these relationships mean to the database more than your average migration. If you have little or no data it would be much simpler to just drop the tables and start over fresh with your migrations.