Skip to content
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

Foreign key field value instead of id without nesting schemas ? #291

Closed
AliGx97 opened this issue Nov 27, 2021 · 4 comments · Fixed by #317
Closed

Foreign key field value instead of id without nesting schemas ? #291

AliGx97 opened this issue Nov 27, 2021 · 4 comments · Fixed by #317

Comments

@AliGx97
Copy link

AliGx97 commented Nov 27, 2021

Hi, is it possible to send a foreign key value without nesting the schemas ? Here's my scenario:

class Department(models.Model):
    id = models.IntegerField(primarty_key=True, editable=False)
    dep = models.CharField(max_length=200, null=False,unique=True)

 class Student(models.Model):
    id = models.IntegerField(primarty_key=True, editable=False)
    name = models.CharField(max_length=200, null=False)
    dep = models.ForeignKey(Department, on_delete=models.CASCADE)


 class DepartmentOut(Schema):
     dep: str
 

 class StudentOut(Schema):
    id: int
    name: str
    dep: DepartmentOut

this will result in an output of:

{
    id: 1000,
    name: 'Some name',
    dep: {
        dep: 'Some Text'
        }
        
}

How can I show the dep string without a nested object called dep? Like the below shape of JSON:

{
    id: 1000,
    name: 'Some name',
    dep: 'Some Text'
    
}

I tried searching without any luck, thanks in advance.

@dvrg
Copy link

dvrg commented Nov 29, 2021

You can nested DepartmentOut via StudentOut parameter like this

class DepartmentOut(Schema):
     dep: str
 

 class StudentOut(DepartmentOut):
    id: int
    name: str

@vitalik
Copy link
Owner

vitalik commented Nov 29, 2021

@AliGx97

  1. you can add some property for student for department name:
 class Student(models.Model):
    ...
    @property
    def dep_name(self):
           return self.dep.dep
  1. use that property in schema:
 class StudentOut(Schema):
    id: int
    name: str
    dep_name: str
    # or dep: str = Field(..., alias='dep_name')

@AliGx97
Copy link
Author

AliGx97 commented Nov 29, 2021

Thanks a million to you guys. I thought there might be an internal other thing for that matter. Very appreciated and excuse me for taking your time.

@AliGx97 AliGx97 closed this as completed Nov 29, 2021
@mom1
Copy link
Contributor

mom1 commented Nov 29, 2021

Maybe helpful. I don't tested this.

from functools import reduce
from pydantic.utils import GetterDict as GetterDictOrigin


def nested_getattr(obj: object, attr: str, *args):
    def _getattr(obj, attr):
        return getattr(obj, attr, *args)

    return reduce(_getattr, [obj] + attr.split('.'))


class GetterDict(GetterDictOrigin):
    def __getitem__(self, key: str) -> Any:
        try:
            return nested_getattr(self._obj, key)
        except AttributeError as e:
            raise KeyError(key) from e

    def get(self, key: Any, default: Any = None) -> Any:
        return nested_getattr(self._obj, key, default)


class StudentOut(Schema):
    id: int
    name: str
    dep: str = Field(..., alias='dep.dep')

    class Config:
        getter_dict = GetterDict
        orm_mode = True

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 a pull request may close this issue.

4 participants