-
-
Notifications
You must be signed in to change notification settings - Fork 431
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
Use property to alias ForeignKey fields instead of Pydantic alias #1111
base: master
Are you sure you want to change the base?
Conversation
Hi @pmdevita Yeah I guess it worth trying - just wondering will ti work for case like class SomeSchema(ModelSchema):
fkfield_id: int
class Meta:
model = Some
fields = ['id', 'fkfield'] |
Yeah I've been thinking over whether this is going to cause some kind of backwards compatibility problem. But I tested the current master branch and it looks like doing this with a schema already causes trouble. class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
class Meta:
app_label = "tests"
class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
class Meta:
app_label = "tests"
class BookSchema(ModelSchema):
author_id: int = Field(...)
class Meta:
model = Book
fields = "__all__"
pprint(BookSchema.json_schema())
test = BookSchema(author_id=1, name="asdfioj")
print(test) outputs
The schema seems a bit funny, there's only one Same thing here with models. author_test = Author(name="J. R. R. Tolkien", id=1)
model_test = Book(author=author_test, name="The Hobbit", id=1)
schema_test = BookSchema.from_orm(model_test)
print(schema_test) outputs
It might be reasonable to assume that because this behavior just duplicates data, it probably isn't useful and it's unlikely anyone would be relying on it. Here is the output from that test on my branch for comparison.
|
I left the class |
Anything else I can do to help move this along? |
@vitalik Could you take a look at this again and let me know if I need to fix anything? I'd really like to get this merged since I'm using to_camel for all of my API schemas. Thank you! |
@pmdevita does this fix this issue? class SomeSchema(Schema):
field: datetime = Field(None, alias='user.date')
class AnotherSchema(Schema):
some: SomeSchema = None Outputs: {
"some": {"user.date": ""}
} But we want: {
"some": {"field": ""}
} |
It doesn't, this solves an issue specific to foreign keys and alias generators. I'm not sure why you're aliasing like that but maybe AliasPath and AliasChoice can help you if you're trying to access a property on the data being validated |
Is there any reason this hasn't been merged? The handling of alias generators is very buggy currently with foreign keys and it looks like this PR would fix it? |
@vitalik Is there anything you'd like to me to change with this? It would be nice to have it merged |
Fixes #828 and helps with #469. Full explanation here. Apologies if this explanation isn't quite clear, I'm definitely struggling to explain this properly lol.
Currently for ModelSchema, Ninja uses Pydantic aliases to alias between a ForeignKey field's property name as defined by the user, and the attribute name which holds the ID referenced by the foreign key (
author
vsauthor_id
). However, this prevents users from using Pydantic'salias_generator
with ForeignKey field names.This PR removes the alias and then changes the property name on the Pydantic model to match the attribute name on the Django model (
author_id
), which should allow for data dumped out withmy_schema.model_dump()
to still correctly match up to Django fields as it does now. It then addsproperty
fields to alias between the attribute name and the property name, so any accesses on the model, likemy_schema.author
, will get aliased to the real property name,my_schema.author_id
.Let me know if there are any changes I need to make. I'm going to also write some tests to polish this off.