I am new to django .I have been following the book Practical Django Projects for learning it.
I am creating a weblog as mentioned in the book. I have followed all the steps for writing the Entry model. When the try to add an entry from the admin interface I get the error
DatabaseError at /adminlebron/entry/add/
table lebron_entry has no column named slug
After searching for a bit I found that I ran syncdb before creating the model fully and from the django documentation I found that Syncdb will not alter existing tables . After that I found South( http://south.aeracode.org/ ) and I tried using it , but i am still getting the same error.
This is my Entry Model
class Entry(models.Model):
STATUS_CHOICES = (
(1,'Live'),
(2,'Draft'),
)
title = models.CharField(max_length=250)
excerpt = models.TextField(blank=True)
body = models.TextField()
pub_date = models.DateTimeField(default=datetime.datetime.now)
slug = models.SlugField(help_text="Slug")
author = models.ForeignKey(User)
enable_comments = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
status = models.IntegerField(choices=STATUS_CHOICES,default=1)
categories = models.ManyToManyField(Category)
tags = TagField()
excerpt_html = models.TextField(editable=False,blank=True)
body_html = models.TextField(editable=False,blank=True)
def save(self):
self.body_html = markdown(self.body)
if self.excerpt:
self.excerpt_html = markdown(self.excerpt)
super(Entry,self).save()
class Meta:
verbose_name_plural = "Entries"
ordering = ['-pub_date']
class Admin:
pass
def __unicode__(self):
return self.title
def get_absolute_url(self):
return "/weblog/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(),self.slug)
This is the output of sqlall
BEGIN;
CREATE TABLE "lebron_category" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(250) NOT NULL,
"slug" varchar(50) NOT NULL UNIQUE,
"description" text NOT NULL
)
;
CREATE TABLE "lebron_entry_categories" (
"id" integer NOT NULL PRIMARY KEY,
"entry_id" integer NOT NULL,
"category_id" integer NOT NULL REFERENCES "lebron_category" ("id")
UNIQUE ("entry_id", "category_id")
)
;
CREATE TABLE "lebron_entry" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(250) NOT NULL,
"excerpt" text NOT NULL,
"body" text NOT NULL,
"pub_date" datetime NOT NULL,
"slug" varchar(50) NOT NULL,
"author_id" integer NOT NULL REFERENCES "auth_user" ("id"),
"enable_comments" bool NOT NULL,
"featured" bool NOT NULL,
"status" integer NOT NULL,
"tags" varchar(255) NOT NULL,
"excerpt_html" text NOT NULL,
"body_html" text NOT NULL
)
;
CREATE INDEX "lebron_entry_56ae2a2a" ON "lebron_entry" ("slug");
CREATE INDEX "lebron_entry_337b96ff" ON "lebron_entry" ("author_id");
COMMIT;
It appears that the column slug is there in the table after all.
I don't want to recreate the db is there any other way to correct this? The name of my app is lebron
Related
I have two models:
class StateTax(models.Model):
name = models.CharField(max_length=256)
abbr = models.CharField(max_length=64, primary_key=True)
rate = models.IntegerField(default=0)
class Account(models.Model):
name = models.CharField(max_length=32)
tax_regions = models.ManyToManyField(SalesTaxRegion, blank=True, null=True, related_name="accounts")
However the SQL Django creates during syncdb seems to ignore the primary_key option. For example:
CREATE TABLE `airship_salestaxregion` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(256) NOT NULL,
`abbr` varchar(64) NOT NULL,
`rate` integer NOT NULL
)
;
CREATE TABLE `airship_account_tax_regions` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`account_id` integer NOT NULL,
`salestaxregion_id` integer NOT NULL,
UNIQUE (`account_id`, `salestaxregion_id`)
)
;
(note there is still an ID column in the first table and the relationship table references it)
As Like It says in the comment, you're getting your tables mixed up, you've given us python code for StateTax, not SalesTaxRegion.
I've tested your StateTax code with Django 1.4 and Postgres 9.2 and I get the following -
-- DROP TABLE testing_statetax;
CREATE TABLE testing_statetax
(
name character varying(256) NOT NULL,
abbr character varying(64) NOT NULL,
rate integer NOT NULL,
CONSTRAINT testing_statetax_pkey PRIMARY KEY (abbr)
)
There's no additional id field added.
I've got a tiny little problem that, unfortunately, is taking all my time.
It is really simple, I already have my database and I created then modified models.py, and admin.py. Some staff users, who will need to enter values in my database, need the simpliest form to do so.
Here is my database :
-- Table NGSdb.line
CREATE TABLE IF NOT EXISTS `NGSdb`.`line` (
`id` INT NOT NULL AUTO_INCREMENT ,
`value` INT NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE UNIQUE INDEX `value_UNIQUE` ON `NGSdb`.`line` (`value` ASC) ;
-- Table NGSdb.run_has_sample_lines
CREATE TABLE IF NOT EXISTS `NGSdb`.`run_has_sample_lines` (
`line_id` INT NOT NULL ,
`runhassample_id` INT NOT NULL ,
PRIMARY KEY (`line_id`, `runhassample_id`) ,
CONSTRAINT `fk_sample_has_line_line1`
FOREIGN KEY (`line_id` )
REFERENCES `NGSdb`.`line` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_sample_has_line_run_has_sample1`
FOREIGN KEY (`runhassample_id` )
REFERENCES `NGSdb`.`run_has_sample` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
-- Table NGSdb.run_has_sample
CREATE TABLE IF NOT EXISTS `NGSdb`.`run_has_sample` (
`id` INT NOT NULL AUTO_INCREMENT ,
`run_id` INT NOT NULL ,
`sample_id` INT NOT NULL ,
`dna_quantification_ng_per_ul` FLOAT NULL ,
PRIMARY KEY (`id`, `run_id`, `sample_id`) ,
CONSTRAINT `fk_run_has_sample_run1`
FOREIGN KEY (`run_id` )
REFERENCES `NGSdb`.`run` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_run_has_sample_sample1`
FOREIGN KEY (`sample_id` )
REFERENCES `NGSdb`.`sample` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
Here is my models.py :
class Run(models.Model):
id = models.AutoField(primary_key=True)
start_date = models.DateField(null=True, blank=True, verbose_name='start date')
end_date = models.DateField(null=True, blank=True, verbose_name='end date')
project = models.ForeignKey(Project)
sequencing_type = models.ForeignKey(SequencingType)
def __unicode__(self):
return u"run started %s from the project %s" % (self.start_date,self.project)
class Line(models.Model):
id = models.AutoField(primary_key=True)
value = models.IntegerField()
def __unicode__(self):
return u"%s" % str(self.value)
class RunHasSample(models.Model):
id = models.AutoField(primary_key=True)
run = models.ForeignKey(Run)
sample = models.ForeignKey(Sample)
dna_quantification_ng_per_ul = models.FloatField(null=True, blank=True)
lines = models.ManyToManyField(Line)
def __unicode__(self):
return u"Sample %s from run %s" % (self.sample, self.run)
And here is my admin.py :
class RunHasSamplesInLine(admin.TabularInline):
model = RunHasSample
fields = ['sample', 'dna_quantification_ng_per_ul', 'lines']
extra = 6
class RunAdmin(admin.ModelAdmin):
fields = ['project', 'start_date', 'end_date', 'sequencing_type']
inlines = [RunHasSamplesInLine]
list_display = ('project', 'start_date', 'end_date', 'sequencing_type')
As you can see, my samples are displayed in lines in the run form so that the staff can easily fullfill the database.
When I try to fill the database I have this error :
(1054, "Unknown column 'run_has_sample_lines.id' in 'field list'")
Of course, there are no field "lines" in my database ! It is a many to many field so I already created my intermediate table !
Okay okay ! So I tried to create the model for the intermediate table (run_has_sample_lines) and add a "through" to the ManyToManyField in the RunHasSample model. But, as I add manually the "through", I cannot use the ManyToMany field. The only way to add lines to the admin view is to stack them in lines... As you can see the samples are already in lines, it is impossible to put a new "inlines" in the already in lines samples...
Finally, I just tried to see what django had created with the manage.py sqlall.
I see that :
CREATE TABLE `run_has_sample_lines` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`runhassample_id` integer NOT NULL,
`line_id` integer NOT NULL,
UNIQUE (`runhassample_id`, `line_id`)
)
;
ALTER TABLE `run_has_sample_lines` ADD CONSTRAINT `line_id_refs_id_4f0766aa` FOREIGN KEY (`line_id`) REFERENCES `line` (`id`);
It seems that there are no foreign key on the run_has_sample table whereas I created it in the database in the first place. I guess that the problem is coming from here but I cannot resolve it and I really hope that you can...
Thank you very much !
you may wish to try a 'through' attribute on the many-to-many relationship and declare your intermediate table in Django.
I found where the problem is...
It is not a problem in the ManyToManyField but in the intermediate table. Django refused that my intermediate table doesn't have an unique id !
So, in the sql which created django, it created automatically an unique id named "id", but in my database I didn't create one (because the couple of two foreign key is usually enough).
Next time, I'll be more carefull.
I have tested to "inspectdb" but I think my schema is to complex, for
example... for the table "tdir_files_context" (djangoinspectdb.JPG
"image in attachment") I got this model:
class TdirFilesContext(models.Model):
id_category = models.ForeignKey(TdirCategories, db_column='id_category')
id_file_context = models.CharField(max_length=20)
n_file_context = models.CharField(max_length=150)
coment = models.CharField(max_length=2000)
id_user_db_ins = models.CharField(max_length=45)
id_user_db_upd = models.CharField(max_length=45)
id_user_sys_ins = models.CharField(max_length=45)
id_user_sys_upd = models.CharField(max_length=45)
date_ins = models.DateTimeField()
date_last_upd = models.DateTimeField()
class Meta:
db_table = u'tdir_files_context'
This database table have Two primary keys and One foreign key. The
Django Model handle this kind of database tables?
First, no table can have two primary keys. That's just not possible. I'll just assume yours has a primary key composed of two columns, id_category and id_file_context.
Unfortunately, Django doesn't currently support models with composite primary keys, it can only handle tables with exactly one columns as their primary key.
<plug type="shameless">There is work underway on making this possible with Django, see https://code.djangoproject.com/ticket/373 and my work on this from last Google Summer of Code: https://github.com/koniiiik/django </plug>
Other than that though, ForeignKeys are perfectly fine with Django and I see no other problems with your table.
koniiiik just brought a very interesting answer about composite primary keys.
But when I see your definition of the model, I'm not sure you really want two primary keys, but just one foreign key and one primary key as :
class TdirCategories(models.Model):
id_category = models.AutoField(primary_key=True)
class TdirFilesContext(models.Model):
id_category = models.ForeignKey(TdirCategories, db_column='id_category')
id_file_context = models.AutoField(primary_key=True)
n_file_context = models.CharField(max_length=150)
coment = models.CharField(max_length=2000)
id_user_db_ins = models.CharField(max_length=45)
id_user_db_upd = models.CharField(max_length=45)
id_user_sys_ins = models.CharField(max_length=45)
id_user_sys_upd = models.CharField(max_length=45)
date_ins = models.DateTimeField()
date_last_upd = models.DateTimeField()
class Meta:
db_table = u'tdir_files_context'
the command python manage.py syncdb executes it well and after a python manage.py name_of_your_app_containing_the_model sql
You get a correct :
BEGIN;
CREATE TABLE "app_tdircategories" (
"id_category" integer NOT NULL PRIMARY KEY
)
;
CREATE TABLE "tdir_files_context" (
"id_category" integer NOT NULL REFERENCES "app_tdircategories" ("id_category"),
"id_file_context" integer NOT NULL PRIMARY KEY,
"n_file_context" varchar(150) NOT NULL,
"coment" varchar(2000) NOT NULL,
"id_user_db_ins" varchar(45) NOT NULL,
"id_user_db_upd" varchar(45) NOT NULL,
"id_user_sys_ins" varchar(45) NOT NULL,
"id_user_sys_upd" varchar(45) NOT NULL,
"date_ins" datetime NOT NULL,
"date_last_upd" datetime NOT NULL
)
;
COMMIT;
hope it helps :)
I have class SubForum with ForeignKey to self - parent:
class Forum(models.Model):
name = models.CharField(max_length=200)
url = models.URLField()
class SubForum(models.Model):
name = models.CharField(max_length=200)
orginal_id = models.IntegerField()
forum = models.ForeignKey('Forum')
parent = models.ForeignKey('self', null=True, blank=True)
I want to allow for null and blank enteries - I saw examples that this is a proper way to do that.
In sql view everything is ok:
BEGIN;CREATE TABLE "main_forum" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(200) NOT NULL,
"url" varchar(200) NOT NULL
)
;
CREATE TABLE "main_subforum" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(200) NOT NULL,
"orginal_id" integer NOT NULL,
"forum_id" integer NOT NULL REFERENCES "main_forum" ("id"),
"parent_id" integer
)
;COMMIT;
In parent_id field there is no NOT NULL, but when I want to add new SubForum using admin panel without setting parent i get error:
Cannot assign None: "SubForum.parent" does not allow null values.
What's wrong?
I made some changes, reverted it back and now everything is working fine... and I don't see any difference with code that I posted here...
Should I delete question?
My DjangoApp is using categories to generate a navigation and to put stuff in those categories.
There are two types of categories:
ParentCategories (top categories)
ChildCategories (sub categories that have a ParentCategory as a parent)
Because those to categories are so similar I don't want to use two different models.
This is my category model:
class Category(models.Model):
name = models.CharField(max_length=60)
slug = models.SlugField(max_length=80, blank=True)
is_parent = models.BooleanField()
parent = models.ForeignKey('self', null=True, blank=True)
In my djangoadmin the parent won't be represented.
If I use python manage.py sql I get:
CREATE TABLE "catalog_category" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(60) NOT NULL,
"slug" varchar(80) NOT NULL,
"is_parent" bool NOT NULL
)
;
So the parent relationship won't even be created.
Is there a handy way of fixing this?
I know I could just alter the table but I'm flushing/deleting the database quite a lot because the app changes rapidly and I don't want to alter the table everytime manually.
btw: my dev db is of course sqlite3.
On the server we'll use postgresql
Something else is going on - that definition of parent is fine. If I run manage.py sql on an app with that model copy-pasted in, I get:
BEGIN;
CREATE TABLE "bar_category" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(60) NOT NULL,
"slug" varchar(80) NOT NULL,
"is_parent" bool NOT NULL,
"parent_id" integer
)
;
COMMIT;