I'm attempting to run 'syncdb -all' in my django project, having just added this model.
However I'm getting this error message:
django.db.utils.ProgrammingError: column "target_content_type_id" specified more than once
Why is this happening when 'target_content_type_id' is not repeated and not in any other models?
class Action(models.Model):
actor = models.ForeignKey(User)
verb = models.CharField(max_length=500)
action_object_content_type = models.ForeignKey(
ContentType, related_name='action_object', blank=True, null=True
)
action_object_object_id = models.CharField(
max_length=500, blank=True, null=True
)
action_object = generic.GenericForeignKey(
'action_object_content_type', 'action_object_object_id'
)
target_content_type = models.ForeignKey(
ContentType, related_name='target', blank=True, null=True
)
target_content_type_id = models.CharField(
max_length=500, blank=True, null=True
)
target = generic.GenericForeignKey(
'target_content_type', 'target_content_type_id'
)
public = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
When you specify a ForeignKey field, Behind the scenes, Django appends "_id" to the field name to create its database column name.
In this case, your field target_content_type which is a ForeignKey, would correspond to the database column target_content_type_id, which is conflicting with your charfield.
Rename your target_content_type_id to something else like target_content_type_object_id or something unique.
Here is the documentation of ForeignKey and more specifically on Database Representation
Related
Django allows a foreign key to "self" as in
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
verbose_name="User",
related_name="user_profiles",
)
entity = models.ForeignKey(
Entity,
on_delete=models.CASCADE,
verbose_name="Entity",
related_name="entity_profiles",
)
email = models.EmailField(
max_length=255,
help_text=_("Automatically generated to use entity email domain"),
)
supervisor0 = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
verbose_name="Supervisor0",
related_name="supervisor0_profiles",
help_text=_("Employees only."),
)
supervisor1 = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
verbose_name="Supervisor1",
related_name="supervisor1_profiles",
help_text=_(
"Employees only. Only the executive head is his/her own \
supervisor."
),
)
supervisor2 = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
verbose_name="Supervisor2",
related_name="supervisor2_profiles",
help_text=_(
"Employees only. Only the executive head is his/her own \
supervisor."
),
)
supervisor3 = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
verbose_name="Supervisor3",
related_name="supervisor3_profiles",
help_text=_(
"Employees only. Only the executive head is his/her own \
supervisor."
),
)
The supervisor0 is the user and being supervisor0 identifies him/her as an employee. The other supervisors also have to be already in the database for them to be able to be referenced.
The help_texts explain the situation of the executive head.
The question is how to test these relationships to "self". I have no problem with relationships to other models.
Using pytest, I record only supervisor0 in the ProfileFactory for the moment.
class ProfileFactory(factory.django.DjangoModelFactory):
class Meta:
model = Profile
user = factory.SubFactory(UserFactory)
entity = factory.SubFactory(EntityFactory)
supervisor0 = user
An assertion error should be thrown up if there is no supervisor1:
def test_profile_supervisor0_and_no_supervisor1():
left = "supervisor0" and "supervisor1"
right = "supervisor0" and not "supervisor1"
assert left == right
It is! The problem is the intergrity errors which accompy the results.
They say
ERROR internalcontrol/tests/test_models.py::test_profile_str - django.db.utils.IntegrityError: duplicate key value violates unique constraint "users_user_username_key"
ERROR internalcontrol/tests/test_models.py::test_profile_get_absolute_url - django.db.utils.IntegrityError: duplicate key value violates unique constraint "users_user_username...
They refer to previous string and get_absolute_url tests which pass in the absence of the "self" relationship.
The problem is - how does one test foreign keys to self?
Hej! :)
I have 5 models which are connected hierarchical with each other.
Section -> division -> group -> class -> wz
one section can have multiple divisions, but one division can only have one section (and so on). Therefor I have ForeignKeys set:
# models.py
class NaceSection(models.Model):
code = models.CharField(max_length=1, unique=True)
description_english = models.CharField(max_length=500)
class NaceDivision(models.Model):
code = models.CharField(max_length=2, unique=True)
nace_section = models.ForeignKey(NaceSection, on_delete=models.CASCADE, related_name="nace_section")
description_english = models.CharField(max_length=500)
class NaceGroup(models.Model):
nace_division = models.ForeignKey(NaceDivision, on_delete=models.CASCADE, related_name="nace_division")
code = models.CharField(max_length=4, unique=True)
description_english = models.CharField(max_length=500)
I than have a model where all those are integrated as M2M fields with a dropdown option.
My goal is to only get the divisions which are in the already selected section in the admin area. (and so on)
I tried smart-select ChainedForeignKey:
# models.py
class Institution(models.Model):
nace_sections = models.ManyToManyField(
NaceSection,
related_name="nace_sections"
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_sections',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_divisions',
blank=True,
)
The organisation and dropdown in the admin area do not change at all and my view with a table of all my results tells me ('42S22', "[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'nace_divisions_id'. (207) (SQLExecDirectW)")
With the ChainedManyToManyField nothing at all happens. Does anybody know what's going wrong?
Any help appreciated! :)
nace_sections is specified as models.ManyToManyField in your code
1.Change from ManyToManyField to ForeignKey.
2.Rename chained_model_field values
-->nace_sections to nace_section
-->nace_divisions to nace_division
class Institution(models.Model):
nace_sections = models.ForeignKey(
NaceSection,
related_name="nace_sections"
, on_delete=models.CASCADE
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_section',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_division',
blank=True,
)
We have defined two apps: Manin_matrix and SW_matrix.
We want the field name (project_name) present in class GENERAL_t of models.py file inside Main_matrix app to be inside the models.py file of SW_matrix app.
Basically, project_name_work field in class EDVT of SW_matrix models.py should be the same as project_name of Main_matrix app.
We want this so that in a database for EDVT table we will get the same project id along with the project name.
Main_matrix/models.py
class GENERAL_t(models.Model):
project_name = models.CharField(
blank=True,
null=True,
max_length=40,
verbose_name='Project_Name'
)
platform = models.CharField(
blank=True,
null=True,
max_length=40,
verbose_name='Platform SW'
)
SW_matrix/models.py
class EDVT(models.Model):
project_rel=models.ForeignKey(
GENERAL_t,
null=True,
on_delete=models.SET_NULL,
verbose_name="Choose Project"
)
project_name_work = models.ForeignKey(
GENERAL_t.project_name,
null=True,
verbose_name='Project_Name'
)
You don't need to do that, and a FK won't allow that. The FK field is just the ID of a row in another table, nothing more complex than that really.
When working with ForeignKey links like this it's a good idea to use strings so that you don't have to import the related model. The format of the string is '<appname.ModelName>
For example, I link an object to a (django) content type like this;
source_content_type = models.ForeignKey(
verbose_name=_('source content type'),
to='contenttypes.ContentType',
on_delete=models.CASCADE
)
So to link your EDVT model to a GENERAL_t you'd do;
class EDVT(models.Model):
general_t = models.ForeignKey(
to='Manin_matrix.GENERAL_t',
null=True,
verbose_name='general t'
)
Then if EDVT needs to be able to return a project_name you could do it as a property.
class EDVT(models.Model):
project_rel = models.ForeignKey(
to='Manin_matrix.GENERAL_t',
null=True,
verbose_name='Project_Name'
)
#property
def project_name(self):
return self.project_rel.project_name
Then you can access it either by EDVT.objects.first().project_name or if you didn't implement the property you can do EDVT.objects.first().general_t.project_name (or any other field on that model)
Env: Django 1.8.11 + Postgis
I'm adding some ForeignKeys on a MyModel.
The models pointed are in another schema ("cartography").
makemigrations
no errors
migrate
One error. Can't create the constraint because the generated name.
But I'm adding 10 fields, really similar between them. Only one is giving that stupid error.
I can't specify the constraint name anywhere.
class myModel(models.Model)
zps_calculated = models.ForeignKey( Cartography_zps, verbose_name="zps_calcolato", null=True, blank=True, on_delete=models.SET_NULL)
zsc_sic_sir_calculated = models.ForeignKey( Cartography_zsc_sic_sir, verbose_name="zsc_sic_sir_calcolato", null=True, blank=True, on_delete=models.SET_NULL)
manyothersdata = "xxx"
That is the slice of code generated from sqlmigrate (to inspect the code the migration generate).
As you see the name of the constraint is the error.
1 on 10 fields is giving the error
CREATE INDEX "segnalazioni_f38ba181" ON "segnalazioni" ("zps_calculated_id");
ALTER TABLE "segnalazioni" ADD CONSTRAINT "se_zps_calculated_id_6844dce0603174b2_fk_"cartography"."zps"_id" FOREIGN KEY ("zps_calculated_id") REFERENCES "cartography"."zps" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "segnalazioni_eb52e53f" ON "segnalazioni" ("zsc_sic_sir_calculated_id");
ALTER TABLE "segnalazioni" ADD CONSTRAINT "cc6ce48808e3a5292779a9787d21e5ad" FOREIGN KEY ("zsc_sic_sir_calculated_id") REFERENCES "cartography"."zsc_sic_sir" ("id") DEFERRABLE INITIALLY DEFERRED;
That is the name giving the error: "se_zps_calculated_id_6844dce0603174b2_fk_"cartography"."zps"_id"
I think should be something like:
"6844dce0603174b2..."
the model NOT giving the error:
class Cartography_zsc_sic_sir(models.Model):
id = models.AutoField(primary_key=True)
slug = models.CharField(max_length=40, blank=True, null=True)
nome = models.CharField(max_length=60, blank=True, null=True)
the_geom = models.MultiPolygonField(srid=23032, blank=True, null=True )
objects = models.GeoManager()
class Meta:
managed = False
db_table = '"cartography"."zsc_sic_sir"'
verbose_name = 'Cartography - zsc_sic_sir'
verbose_name_plural = 'Cartography - zsc_sic_sir'
ordering = ["id","slug"]
def __unicode__(self):
return self.nome
that is the model giving the error:
class Cartography_zps(models.Model):
id = models.AutoField(primary_key=True)
slug = models.CharField(max_length=40, blank=True, null=True)
the_geom = models.MultiPolygonField(srid=23032, blank=True, null=True )
objects = models.GeoManager()
class Meta:
managed = False
db_table = '"cartography"."zps"'
verbose_name = 'Cartography - ZPS'
verbose_name_plural = 'Cartography - ZPS'
ordering = ["id","slug"]
def __unicode__(self):
return self.slug
Going further I'm investigating in Django code, backwards.
The
' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %
is in
/django/db/backends/base/creation.py row 180
using that
qn = self.connection.ops.quote_name
that SHOULD be the %s constraint name value:
qn(truncate_name(r_name, self.connection.ops.max_name_length()))
Anyone have an hint to help me?
I'm gonna look what qn does.
https://github.com/django/django/releases/tag/1.8.11
The problem was the attribute name (but I still dunno why):
zps_calculated = models.ForeignKey( Carto...
I renamed it to
zpsasd_calculated = models.ForeignKey( Carto
and the generated constraint name changed to (sqlmigrate):
a326518e5e22b0c2c1251e5bbb331adb
Wow!
Renamed the attribute zpsasd_calculated to zps_calculated, with another migration.
Worked.
Next time I will migrate with custom SQL
https://www.ralphlepore.net/custom-foreign-key-constraints-with-django/
This is are my models i want to relate. i want for collection to appear in the form of occurrence.
class Collection(models.Model):
id = models.AutoField(primary_key=True, null=True)
code = models.CharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
collection_name = models.CharField(max_length=100)
def __unicode__(self):
return self.collection_name
class Meta:
db_table = u'collection'
ordering = ('collection_name',)
class Occurrence(models.Model):
id = models.AutoField(primary_key=True, null=True)
reference = models.IntegerField(null=True, blank=True, editable=False)
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
modified = models.DateTimeField(null=True, blank=True, auto_now=True)
class Meta:
db_table = u'occurrence'
Every time i go to check the Occurrence object i get this error
TemplateSyntaxError at /admin/hotiapp/occurrence/
Caught an exception while rendering: column occurrence.collection_id does not exist
LINE 1: ...LECT "occurrence"."id", "occurrence"."reference", "occurrenc..
And every time i try to add a new occurrence object i get this error
ProgrammingError at /admin/hotiapp/occurrence/add/
column occurrence.collection_id does not exist
LINE 1: SELECT (1) AS "a" FROM "occurrence" WHERE "occurrence"."coll...
What am i doing wrong? or how does ForeignKey works?
The problem is that you have not updated your database table definition since adding the ForeignKey. syncdb doesn't do this for you, as the documentation clearly states. You need to update the SQL manually, or use a tool like South.
Are you sure you mean
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
Nullable and Unique? This may not be possible in some databases.
Generally, the unique constraint doesn't seem to make much sense here.
Are you trying to force a 1-to-1 relationship? Use the OneToOneField. http://docs.djangoproject.com/en/1.1/ref/models/fields/#django.db.models.OneToOneField