Skip to content

Refs #35224 -- Removed special-case GenericForeignKey system check. #17886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

adamchainz
Copy link
Member

ticket-35224

Profiling checks after 6002df0 was merged, I found that check_generic_foreign_keys() was taking ~2% of the total time. It seems that iterating over all fields of all models is fairly expensive.

The special check function can be eliminated now that GenericForeignKey if we make Model._check_fields cover private fields as well. That seems like a change we’d want anyway.

@adamchainz
Copy link
Member Author

adamchainz commented Feb 19, 2024

Ah, this has made GenericRelation checks run, causing a lot of failures. It looks like they never ran before because private fields weren’t being checked. I have added GenericRelationTests.test_generic_relation_checks_are_performed to check this, and it fails on main.

To fix the failures, I think we’ll need to either modify the test models or the checks that are enabled in GenericRelation. I’m not sure which yet, any input welcome.

Comment on lines +414 to +417
class GfkModel(models.Model):
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType, models.CASCADE)
gfk = GenericForeignKey()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for the below GenericRelation to have something to refer to, otherwise the contenttypes.E004 check fails.

Comment on lines +8 to +10
content_type = models.ForeignKey(ContentType, models.CASCADE, related_name="+")
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, fields required to fill in for GenericRelations below, preventing contenttypes.E004 errors.

Comment on lines +1792 to +1793
for field in cls._meta.private_fields:
errors.extend(field.check(**kwargs))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One outstanding wrinkle: private_fields are copied into subclasses, so checks for one field get repeated in subclasses.

I don’t think there’s a way with the current attributes to tell if a field is local and private right now. Maybe more attributes or reorganization could work.

@@ -357,7 +357,7 @@ def __init__(

def check(self, **kwargs):
return [
*super().check(**kwargs),
*self._check_field_name(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the fix to make the GenericRelation checks run, the test suite showed many errors: fields.E304, fields.E305, and fields.E311. For example:

aggregation_regress.HardbackBook.tags: (fields.E311) 'ItemTag.book_ptr' must be unique because it is referenced by a foreign key.
    HINT: Add unique=True to this field or add a UniqueConstraint (without condition) in the model Meta.constraints.

generic_relations_regress.Cafe.links: (fields.E304) Reverse accessor 'Link.places' for 'generic_relations_regress.Cafe.links' clashes with reverse accessor for 'generic_relations_regress.Place.links'.
    HINT: Add or change a related_name argument to the definition for 'generic_relations_regress.Cafe.links' or 'generic_relations_regress.Place.links'.

I think these are false positives. The easiest way to prevent them was to modify GenericRelation.check() to not call super(), like GenericForeignKey.check(). I tried to look through all existing checks for what’s relevant, and the field name check is the only one that really stood out.

@adamchainz adamchainz marked this pull request as draft March 11, 2024 21:22
@nessita
Copy link
Contributor

nessita commented Jan 31, 2025

@adamchainz I'm reviewing code around ticket-35224 to do a full review of ticket-36151. Is this PR still relevant? Could we close it if not?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants