Skip to content

Commit 6ecc082

Browse files
migeed-zmeta-codesync[bot]
authored andcommitted
Correctly synthesize pk and id types based on custom pk info
Reviewed By: rchen152 Differential Revision: D85589929 fbshipit-source-id: 820238d8c8eabe7e27fdf6430d44f5251ab847ba
1 parent 9705b0f commit 6ecc082

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

pyrefly/lib/alt/class/django.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,31 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
197197

198198
let mut fields = SmallMap::new();
199199

200-
let auto_field_export = KeyExport(AUTO_FIELD);
201-
let auto_field_type =
202-
self.get_from_export(ModuleName::django_models_fields(), None, &auto_field_export);
203-
204-
// TODO: Extend the solution to handle custom pk
205-
if let Some(id_type) = self.get_django_field_type(&auto_field_type, cls) {
206-
fields.insert(ID, ClassSynthesizedField::new(id_type.clone()));
207-
fields.insert(PK, ClassSynthesizedField::new(id_type));
200+
let custom_pk_field = metadata
201+
.django_model_metadata()
202+
.and_then(|dm| dm.custom_primary_key_field.as_ref());
203+
204+
if let Some(pk_field_name) = custom_pk_field {
205+
let instance_type = self.as_class_type_unchecked(cls).to_type();
206+
let pk_attr_type = self.attr_infer_for_type(
207+
&instance_type,
208+
pk_field_name,
209+
TextRange::default(),
210+
&self.error_swallower(),
211+
None,
212+
);
213+
fields.insert(PK, ClassSynthesizedField::new(pk_attr_type));
214+
// When there's a custom pk, don't synthesize an `id` field
215+
} else {
216+
// No custom pk, use default AutoField for both id and pk
217+
let auto_field_export = KeyExport(AUTO_FIELD);
218+
let auto_field_type =
219+
self.get_from_export(ModuleName::django_models_fields(), None, &auto_field_export);
220+
221+
if let Some(id_type) = self.get_django_field_type(&auto_field_type, cls) {
222+
fields.insert(ID, ClassSynthesizedField::new(id_type.clone()));
223+
fields.insert(PK, ClassSynthesizedField::new(id_type));
224+
}
208225
}
209226

210227
Some(ClassSynthesizedFields::new(fields))

pyrefly/lib/test/django/auto_generated_fields.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ assert_type(reporter.id, str)
3939
);
4040

4141
django_testcase!(
42-
bug = "do not generate an id field when a custom key is present; wrong pk type",
4342
test_custom_pk,
4443
r#"
4544
from typing import assert_type
@@ -53,13 +52,13 @@ class B(Article):
5352
pass
5453
5554
article = Article()
56-
article.id
55+
article.id # E: Object of class `Article` has no attribute `id`
5756
assert_type(article.uuid, UUID)
58-
assert_type(article.pk, UUID) # E: assert_type(int, UUID)
57+
assert_type(article.pk, UUID)
5958
6059
article2 = B()
61-
article2.id
60+
article2.id # E: Object of class `B` has no attribute `id`
6261
assert_type(article2.uuid, UUID)
63-
assert_type(article2.pk, UUID) # E: assert_type(int, UUID)
62+
assert_type(article2.pk, UUID)
6463
"#,
6564
);

0 commit comments

Comments
 (0)