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.
Related
class Plans(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255)
plan_type = models.CharField(max_length=255)
class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.IntegerField(primary_key=True)
Order's selected_plan_id is Plans's id.
Which model should I add a foreign key to? How?
First of all there are some bad ways to pointout:
two fields cannot be primary keys in a table
also django as default includes primary key id in every table, so no need to add id field.
You should be doing this way:
class Order(models.Model):
selected_plan_id = models.ForeignKey(Plans, on_delete=models.CASCADE)
The solution that you are looking for
class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.ForeignKey(Plans, on_delete=models.CASCADE)
The purpose of using models.CASCADE is that when the referenced object is deleted, also delete the objects that have references to it.
Also i dont suggest to you add 'id' keyword to your property, django makes automatically it. If you add the 'id' keyword to end of the your property like this case, you gonna see the column called 'selected_plan_id_id' in your table.
class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.IntegerField(primary_key=True)
Plain= models.ForeignKey(Plain)
Check the dependence of the table and after getting that made one key as foreign like in this one plain is not depend on the order. But the order depends on the plan.
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.
I have two models:
class Amodel(models.Model):
name = models.CharField(max_length=8)
desc = models.CharField(max_length=256)
class Bmodel(models.Model):
name = models.CharField(max_length=8)
desc = models.CharField(max_length=256)
now I have another model:
class Cmodel(models.Model):
name = models.CharField(max_length=8)
f_model = models.ForeignKey(to='there I want to dynamic refers to Amodle or Bmodel when create the Cmodel instance')
I want the Cmodel's f_model is choosable when Create the Cmodel instance, whether this is possible?
This feature called generic relations. Here is the official documentation link generic-relations
By definition of foreign key you can not assign foreign key to one field with choices of model
A FOREIGN KEY is a key used to link two tables together.
A FOREIGN KEY is a field (or collection of fields) in one table that refers to the PRIMARY KEY in another table.
Instead you can proceed to create two fields as below:
class Cmodel(models.Model):
name = models.CharField(max_length=8)
f_a_model = models.ForeignKey(Amodel, blank=True, null=True, on_delete=models.CASCADE)
f_b_model = models.ForeignKey(Bmodel, blank=True, null=True, on_delete=models.CASCADE)
This way you can create two fields and you can keep it as null.
So If you wish to proceed for Cmodel instance with foreign key of a model you can add it to field f_a_model and keep f_b_model null and vice versa
You may follow example of using generic-relations from this link and the doc.
When you use generic relations you need to write your own custom field and method for serializer or form or anywhere you wish to user it.
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
I have a model like this:
from django.db import models
class House(models.Model):
address = models.CharField(max_length=200)
price = models.CharField(max_length=200)
class Inhabitant(models.Model):
home = models.ForeignKey(House, blank=True, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=200)
age = models.IntegerField()
However when running python manage.py sql my_test_app I get this at the end:
ALTER TABLE `my_test_app_inhabitant`
ADD CONSTRAINT `house_id_refs_id_7cd928c7`
FOREIGN KEY (`home_id`)
REFERENCES `my_test_app_house` (`id`);
This means I can't add an inhabitant without a house - how can I get around this?
The foreign key don't means that you can not add an inhabitant without a house.
The constraint says: 'if Inhabitant.house contains a value then this value must appear in House model'.
To verify that database allow inhabitants withou house you should check that house field inhabitant table allow NULL values.