relation error on adding new model class - django

I have 2 model-classes inside models.py file :
class Certificate(models.Model):
comments = models.TextField(blank=True, default='')
generic_certificate = models.ForeignKey(GenericCertificate, related_name='certificates_awarded')
tag = models.ForeignKey('Tag', related_name='certificates_awarded', null=True, blank=True)
class GenericCertificate(CommonInfo):
CERTIFICATE_TYPE = (('C', 'system created'),
('U', 'user created'))
certificate_icon = models.ImageField(upload_to='certificate/icons', default='defaults/certificate.png')
certificate_type = models.CharField(choices=CERTIFICATE_TYPE, max_length=1, default='C')
template = models.FileField(upload_to='certificate/generic_templates')
They are working fine in django admin , but When I am adding one more model class it starts giving error on hitting Generic certificates option: Included operation : South Migration and syncdb
Exception Type: ProgrammingError
Exception Value:
relation "certificates_genericcertificate" does not exist
LINE 1: SELECT COUNT(*) FROM "certificates_genericcertificate"
newly added model class in same models.py
class PositionCertificate(models.Model):
rewardee = models.CharField(max_length=50, default = '0,0')
org_logo = models.CharField(max_length=50, default = '0,0')
tag_name = models.CharField(max_length=50, default = '0,0')
How to remove this error ? and why this error is coming ?

Error
relation "certificates_genericcertificate" does not exist
means that "certificates_genericcertificate" relation do not exists in your database.
Please do
python manage.py syncdb
and if you are using South you can use
python manage.py migrate
try to hit these commands and if it does not help you, drop your tables/database and recreate tables/database by using syncdb.

Related

You are trying to add a non-nullable field '_response_rendered'; django-markupfield

Upon wanting to add some Markdown to a project, I've decided to install django-markupfield to serve this objective. The only thing is that I've installed my models and associated fields ahead of making this decision; now replacing a TextField with MarkupField.
When attempting to make a migration to adjust for this, the following is brought up:
You are trying to add a non-nullable field '_response_rendered' to answer 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
What would be an appropriate default value to add to the fields that will be prompting for such? I have never been too sure of this question in general when it comes to using Django as well, so clarification would be appreciated.
https://github.com/jamesturk/django-markupfield
class Question(models.Model):
title = models.CharField(max_length=50)
body = MarkupField(
markup_type="markdown",
escape_html=True
)
dated = models.DateField(default=date.today)
user_account = models.ForeignKey(
'users.UserAccount',
on_delete=models.SET_NULL,
null=True, blank=True,
related_name="questions"
)
tags = models.ManyToManyField(Tag, related_name='questions')
objects = models.Manager()
dateranges = DateRangeQuerySet.as_manager()
status = QuestionStatusQuerySet.as_manager()
class Meta:
ordering = ['-dated']
default_manager_name = "objects"
def __str__(self):
return self.title
class Answer(models.Model):
question = models.ForeignKey(
Question,
on_delete=models.CASCADE,
related_name="answers"
)
response = MarkupField(
markup_type="markdown",
escape_html=True
)
dated = models.DateField(auto_now_add=True)
user_account = models.ForeignKey(
'users.UserAccount',
on_delete=models.SET_NULL,
null=True, blank=True,
related_name="answers"
)
You have to add default value.
In the background MarkupField create two fields (source link):
_rendered_field_name = lambda name: "_%s_rendered" % name # noqa
_markup_type_field_name = lambda name: "%s_markup_type" % name # noqa
class MarkupField(models.TextField):
...
def contribute_to_class(self, cls, name):
if self.rendered_field and not cls._meta.abstract:
...
cls.add_to_class(_markup_type_field_name(name), markup_type_field)
cls.add_to_class(_rendered_field_name(name), rendered_field)
super(MarkupField, self).contribute_to_class(cls, name)
setattr(cls, self.name, MarkupDescriptor(self))
The simple solution is provide default value at the time of migration:
So select choice 1 and enter default value. It will be add
default value only for the current migration, so your field is
non-nullable. Argument preserve_default(Django Docs) will be added.
Or provide default value in models.py:
class Question(models.Model):
...
body = MarkupField(
markup_type="markdown",
escape_html=True,
default="SOME VALUE"
)
...
class Answer(models.Model):
...
response = MarkupField(
markup_type="markdown",
escape_html=True,
default="SOME VALUE"
)
...
You can always remove default attribute and run makemigrations/migrate again.
THE BEST PRACTICE IS CREATE BACKUP BEFORE YOU RUN:
python manage.py makemigrations
python manage.py migrate
Try adding null = False to your field and migrate again. This usually works for me!

Django - Existing DB Views and Foreign Keys

I have a simple view on the DB which selects from other DB's tables located on the same MSSQL Server to ultimately serve the collected info as a dropdown to the user.
So far I've added the Model with inspectdb:
class AutPricePlanView(models.Model):
priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'AUT_PricePlanView'
Also I have a second existing (Django Native) Model where I want to use the values from the view for a Dropdown Field (to keep everything in sync):
class PricePlanDownload(models.Model):
requesting_user = models.CharField(blank=True, default=None, max_length=50, null=True)
requested_at = models.DateTimeField(auto_now_add=True)
document = models.FileField(upload_to='documents/price_plan_uploads/%Y/%m/%d', blank=True)
priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING)
Makemigrations works fine but when I try to actually migrate I get the following issue: (shortened it a little bit)
django.db.utils.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Foreign key references object 'AUT_PricePlanView' which is not a user table. (1768) (SQLExecDirectW)")
I would be really grateful if someone had an idea or a workaround since I can't figure out what the heck this has to do with a "user" table...
Since the view is not actually a table, you cannot set Foreign Key constraints. Since ForeignKey's default db_constraint value is True, Django tries to set Foreign Key constraints when performing migrations. This is the reason the migration fails.
So, you can turn off the db_constraint option. And you can remove the existing migration file, and re-create the migration file. Then, the migration will success and you can keep everything in sync.
class PricePlanDownload(models.Model):
... other fields ...
priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING, db_constraint=False)
Pro Tip: You can review migration's SQL using python manage.py sqlmigrate <appname> <migration number>, like python manage.py sqlmigrate yourapp 0002.
Update: You can define __str__ to display the correct value at the dropdown menu.
class AutPricePlanView(models.Model):
priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True, primary_key=True)
# null=False by default. See https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L132
def __str__(self):
return self.priceplan_name
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'AUT_PricePlanView'

django ,model migrate: TypeError: an integer is required (got type str)

I am writing a apps and run makemigrations and migrate multiple time when i add new field.
And now i have added a new foreignKey Field in models and then i run the command:
python3 manage.py makemigrations
after this, i run this command python3 manage.py migrate but it throws me following error
TypeError: an integer is required (got type str)
and later again i run this command pythion3 manage.py migrate --fake and i have successfully migrated and got another problem, when i go to django admin templates and click on my models to add data, it throws me this error:
OperationalError at /admin/booking/seats/
no such column: booking_seats.seat_for_id
I am not getting whats wrong with it, can anyone help me to fix this?
for your reference, see my models:
class Seats(models.Model):
alias = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False
)
seat_no = models.IntegerField(
choices=SeatChoices.choices(),
)
availability = models.IntegerField(
choices=SeatAvailability.choices(),
default=SeatAvailability.AVAILABLE
)
seat_for = models.ForeignKey('booking.show', on_delete=models.CASCADE)
def __str__(self):
return str(self.seat_no)
class Show(models.Model):
alias = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False
)
show_schedule = models.IntegerField(
choices=ShowSchedule.choices(),
)
movie = models.CharField(max_length=50)
def __str__(self):
return str(self.show_schedule)
I just added this new field seat_for = models.ForeignKey('booking.show', on_delete=models.CASCADE) then i facing the problem
Can anyone help me in this case?
I think the problem is that your model is not with a capital, as Python is case sensitive. It should be like this:
seat_for = models.ForeignKey('booking.Show', on_delete=models.CASCADE)

Making use of the users table, causing an error

In Django (2.x) I have an entry form, the model is here:
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class Sample(models.Model):
sample_id = models.AutoField(primary_key=True)
area_easting = models.IntegerField()
area_northing = models.IntegerField()
context_number = models.IntegerField()
sample_number = models.IntegerField()
# taken_by = models.IntegerField()
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.PROTECT)
def __str__(self):
return str(self.sample_id)
class Meta:
db_table = 'samples\".\"sample'
#ordering = ["sample_id"]
managed = False
#verbose_name_plural = "samples"
This works as expected, a list of usernames drops down (while I would like to format - firstname lastname). However, when I return to the main viewing page I see an error.
django.db.utils.ProgrammingError: column sample.taken_by_id does not exist
LINE 1: ...text_number", "samples"."sample"."sample_number", "samples"....
^
HINT: Perhaps you meant to reference the column "sample.taken_by".
Clearly Django is adding the _id to the table name causing the error, I expect because it is a foreign key.
Any ideas how to remedy this behaviour?
You can explicitly set the underlying db column via the db_column attribute:
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column='taken_by', on_delete=models.PROTECT)
https://docs.djangoproject.com/en/2.1/ref/models/fields/#database-representation
^ link to the docs where it specifies that it creates a _id field.
based from the error message you have posted. It seems that your database schema is not updated.
you might need to do manage makemigrations and migrate to apply your model changes to your db schema
e.g
$ python manage.py makemigrations
# to apply the new migrations file
$ python manage.py migrate

How to add ManyToManyField in Existing django model?

I have a follwing two tables:
class Visit(models.Models):
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
date_started = models.DateTimeField(null=True, blank=True)
date_completed = models.DateTimeField(null=True, blank=True)
# Here i want to add ManyToManyField
research = ManyToManyField(ResearchProtocol) #Here i will write for adding the field
class ResearchProtocol(models.Model):
title = models.CharField(max_length=30)
description = models.TextField()
start_date = models.DateField()
end_date = models.DateField()
def __unicode__(self):
return '%s' % self.title
For that i have written sql query :
CREATE TABLE "visit_visit_research" (
"id" serial NOT NULL PRIMARY KEY,
"visit_id" integer NOT NULL REFERENCES "visit_visit" ("id") DEFERRABLE INITIALLY DEFERRED,
"research_id" integer NOT NULL REFERENCES "www_researchprotocol" ("id") DEFERRABLE INITIALLY DEFERRED,
UNIQUE ("visit_id", "research_id")
)
;
When i execute this file the field is created somehow but when i open vist admin
and click to a particular id that leads to change form it gives me the following error:
http://localhost:8000/admin/visit/visit/20/
Exception Type: DatabaseError at /admin/visit/visit/20/
Exception Value: column visit_visit_research.researchprotocol_id does not exist
LINE 1: ...visit_research" ON ("www_researchprotocol"."id" = "visit_vis...
^
Somebody said that you need south and it cannot be done without south. Is that the only solution ? I am using Django 1.3.1, Python 2.7.2.
Can somebody guide me what mistake i am doing?
Any help will be appreciated.
Thanks in advance.
You've called your linking table visit_visit_research, and the field within it research_id, whereas Django is expecting visit_visit_researchprotocol and researchprotocol_id respectively.
Whenever I have modified the table models I used south and these commands to modify the structure and they always worked:
python manage.py convert_to_south "your_app"
python manage.py migrate "your_app"
You could try these and it should work, if you still have south installed.