I am developing a web app using Django. I have created the table in MySQL database and then generated the models.py using inspectdb. I am able to fetch details and connect to the database without any issues. But while saving the values to the particular table, below error is shown
sav_list = List(id=4, item_name ='name1', item_desc='desc1', location='location', reason='rfp', pid=3)
Cannot assign "3": "List.id" must be a "Order" instance.
my models
class List(models.Model):
id = models.IntegerField(db_column='ID', primary_key=True) # Field name made lowercase.
item_name = models.CharField(db_column='Item_Name', max_length=255) # Field name made lowercase.
item_desc = models.CharField(db_column='Item_Desc', max_length=300) # Field name made lowercase.
location = models.CharField(db_column='Location', max_length=100, blank=True, null=True) # Field name made lowercase.
reason = models.CharField(db_column='Reason', max_length=100, blank=True, null=True) # Field name made lowercase.
pid = models.ForeignKey('Order', models.DO_NOTHING, db_column='PID') # Field name made lowercase.
class Order(models.Model):
poid = models.IntegerField(db_column='POID', primary_key=True) # Field name made lowercase.
po = models.CharField(db_column='PO', unique=True, max_length=20) # Field name made lowercase.
quote = models.CharField(db_column='Quote', unique=True, max_length=20) # Field name made lowercase.
condition = models.CharField(db_column='Condition', max_length=15) # Field name made lowercase.
I have tried relate_name for foreign key but still same behaviour. Same values can be stored on database without any issues. Only Django throws an error.
Please someone help me!!!
You should paste the actual error; it is presumably that "List.pid" must be an "Order" instance.
The error should be clear. pid is a ForeignKey field, it expects an instance of the related model. You can either get the item and set it:
pid = Order.objects.get(pk=3)
List(...., pid=pid)
or use the underlying id field:
List(...., pid_id=3)
The pid column at the Django level is not an id (integer), yes on the database level it is. But in Django it is a foreign key, and thus it refers to an Order instance. You thus should pass it an Order instance (the one that corresponds to poid=3).
But we are lucky, in case you construct such ForeignKey, Django automatically makes a field_id column that stores the id, and those two fields act like twins. We can thus assign 3 to pid_id:
sav_list = List(
id=4,
item_name ='name1',
item_desc='desc1',
location='location', reason='rfp',
pid_id=3
)
Note however that for most database backend, foreign key constraints will check if there is an Order instance with as referenced column (in Django the primary key) 3 exists. If not, it is impossible to create such List. I would therefore advice to ensure that such Order exists before trying to save it to the database.
Related
I have my model of User object which is related to Group object (example). So user has something like:
group_name = models.ForeignKey(Group, to_field="group_name", ...)
(of course the group_name is defined as unique as it's not a primary key in Group object)
But when I'm trying to change the group_name value for some Group object (regardless it's via Admin interface or within the code by updating the selected object) it raises the Integrity error: FOREIGN KEY constraint failed
I know there is a mandatory parameter on_delete for the foreign key filed but I've tried all potential pre-defined values (models.SET_DEFAULT, models.CASCADE, etc.) but without any change.
It seems to me I need something what to do on_update, but that's not possible attribute ;-)
Here is some code samples
class Group(models.Model):
members = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='teams', blank=True)
managers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='managed_teams')
# name is short because MySQL does not allow unique char fields to be long
group_name = models.CharField(max_length=128, unique=True, validators=[RegexValidator(r'^[a-zA-Z0-9 ]+$')])
class User(models.Model):
name = models.CharField(max_length=200, default="username", blank=False)
group = models.ForeignKey(Group, null=True, blank=True, on_delete=models.SET_DEFAULT, to_field="name", default="Platform Validation and Testing")
And what I simply do in code (pre-condition is that I have already some objects stored in DB with User - Group relation):
from myapp.models import Group
group = Group.objects.all()[0]
group.name = "Some new cool name"
group.save()
and here is the django.db.utils.IntegrityError: FOREIGN KEY constraint failed
As I mentioned the same happens if I change the Group name field within Admin interface of Django.
When you change the group name, the user which points to the original group name is suddenly pointing to a non-existing group. So you can't do that without first checking if any user is pointing to it. Change your code to first check all users pointing to your group, unset the fk, and then either reset it to the new group_name or leave it unset.
I'm trying to query through a model in Django that has no Primary Key.
I need to query though it so I can access to the Foreign keys it has.
I'm just trying to do this atm and doesn't even work:
chars = Characterweapons.objects.all()
print(chars)
And if i change Characterweapons to Weapons for example, a table with Primary Key it works.
The error I get when I load the page is this:
Exception Value: (1054, "Unknown column 'characterweapons.id' in 'field list'")
This is my model:
class Characterweapons(models.Model):
characterid = models.ForeignKey(Characters, models.DO_NOTHING, db_column='CharacterID') # Field name made lowercase.
weaponid = models.ForeignKey(Weapons, models.DO_NOTHING, db_column='WeaponID', blank=True, null=True) # Field name made lowercase.
categoryid = models.ForeignKey(Category, models.DO_NOTHING, db_column='CategoryID', blank=True, null=True) # Field name made lowercase.
quantity = models.IntegerField(db_column='Quantity', blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'characterweapons'
def __str__(self):
return '%s %s %s %s' % (self.quantity,self.characterid,self.weaponid,self.categoryid)
Anyone knows about this?
Thanks in advance!
So it looks like you did a DBinspect on an existing database to generate this model. I'm guessing this is failing because Django ORM expects your table to have a primary key. "id" is the default name for a Django generated model primary key field. I suspect when you are trying to call Characterweapons.objects.all() it's trying to get the primary key field for some reason.
There may be a workaround but unless you really know what your doing with your database, I would highly urge you to set a primary key on your tables.
The best solution that I found, in this case, was to perform my own query, for example:
fact = MyModelWithoutPK.objects.raw("SELECT * FROM my_model_without_pk WHERE my_search=some_search")
This way you don't have to implement or add another middleware.
see more at Django docs
I have a django movie model
class Film(models.Model):
title = models.CharField(max_length=200)
movie_id = models.CharField(max_length=8, unique=True, primary_key=True)
director = models.ForeignKey('Director', on_delete=models.SET_NULL, null=True)
year = models.IntegerField(null=True)
genres = models.ManyToManyField(Genre)
I need to use movie_id as primary key, but also i need a field, which represents number of item's row in table.
It must increment automatically, just like standard "id" field.
How can i add it?
This question https://stackoverflow.com/users/3404040/take-care is similar, but i can't use my "number" field as primary key, because movie_id is already used for that.
You can use something like this, but it can be resource consuming if you do not want to use the default id field.
class Film(models.Model):
def number():
no = Film.objects.count()
return no + 1
movie_row = models.IntegerField(unique=True,default=number)
From Django's Documentation:
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
If you’d like to specify a custom primary key, just specify primary_key=True on one of your fields. If Django sees you’ve explicitly set Field.primary_key, it won’t add the automatic id column.
Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
If you want yours to explicitly be called movie_id you probably need something like:
class Film(models.Model):
movie_id = models.AutoField(primary_key=True)
My requirement is: create category and product table according to the store selected.
class Category(models.Model):
parent = models.ForeignKey("Category", blank=True, null=True,
related_name="children", verbose_name=_("Parent Category"))
name = models.CharField(verbose_name=_("Name"), max_length=255)
path = models.CharField(verbose_name=_("Path"), max_length=200)
description = models.TextField(verbose_name=_("Description"))
class CategoryStore(model.Model):
default = models.ForeignKey("Category", related_name="store_category",
verbose_name=_("Default Value"))
parent = models.ForeignKey("CategoryStore", blank=True, null=True,
related_name="children", verbose_name=_("Parent Category"))
name = models.CharField(verbose_name=_("Name"), max_length=255)
description = models.TextField(verbose_name=_("Description"))
store = models.ForeignKey("Store", related_name="store_category",
verbose_name=_("Store"))
CategoryStore model will have table names as category_store_1, category_store_2, etc. Would like to create the tables on the fly after a store is created. If, we add another field to the model, should have option to add to all the tables the new field.
class Product(models.Model):
name = models.CharField(verbose_name=_("Name"), max_length=255)
description = models.TextField(verbose_name=_("Description"))
class ProductStore(model.Model):
default = models.ForeignKey("Product", related_name="store_product",
verbose_name=_("Default Value"))
name = models.CharField(verbose_name=_("Name"), max_length=255)
description = models.TextField(verbose_name=_("Description"))
store = models.ForeignKey("Store", related_name="store_product",
verbose_name=_("Store"))
This also has same requirement as the category. One addition is that, option to create new field to both the model, new field on the fly from admin form. It will be attributes for the product. Instead of another table to store attribute values, want to add a new field to the Product and ProductStore model on the fly.
Not sure if I fully understand your problem, but it seems to me that you should reconsider your database structure. I'm not very experienced but adding tables to db on a regular basis on the fly is not good.
CategoryStore model will have table names as category_store_1, category_store_2, etc.
Keeping in mind that in django 1 model <=> 1 db table, try this approach: one table called CategoryStore which holds data from all your stores and another table called CategoryStoreType with the following structures:
CategoryStore has all the fields you need plus a type field which is a foreign key to CategoryStoreType. CategoryStoreType contains a short description of each store type, e.g. a tuple ('id', 'type name'). This way when you need a new field for one store type you simply add another field to CategoryStore, which holds data of all your store types. (Again, as for tables, adding fields on the fly is not that good, imho.)
The Model class are generated by the django inspectdb and i can see the Id field, this is converted from the Legacy tables, the table cant be altered here,
class workFlowTemplate(models.Model):
rev = models.IntegerField(null=True, blank=True)
revtype = models.IntegerField(null=True, blank=True)
**id = models.IntegerField(null=True, blank=True)**
name = models.CharField(max_length=255, blank=True,primary_key=False)
class Meta:
db_table = 'workflow_template'
the problem is when i try to run the django it throws error
CommandError: One or more models did not validate:
pHApp.workflowtemplate: "id": You can't use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.
Note
the id is not primary key here in this case,
When i tries to change
id = models.IntegerField(null=True, blank=True,primary_key=False)
the Issue still remains the same, and same error is repeated again, how to avoid this Issue ?
A model must have a primary key, so you need specify a primary key field, like this:
my_primary_key = models.AutoField(primary_key=True)
id = models.IntegerField(null=True, blank=True)
then it won’t add the automatic id column and you will not receive this error.
Column id is adding by django by default, if you did not specified another field as PK.
In your case, you specified id as your field, but you did not specified what field should be a primary key.
Solution - set another field as primary key since you can not rename id