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

get doctype name statically #26412

Closed
wants to merge 1 commit into from
Closed

Conversation

KlausH09
Copy link
Contributor

@KlausH09 KlausH09 commented May 11, 2024

This pull request introduces a new static method, get_doctype_name, to the base Document class in Frappe. The goal of this enhancement is to facilitate type-safe interactions with documents, particularly when using the frappe.get_doc function. By implementing get_doctype_name, developers can retrieve the Doctype name directly from the class, improving maintainability and readability of the code that interacts with Frappe's ORM layer.

Questions for the Maintainers

Before finalizing this implementation, I'd like to verify if there's an existing method or pattern within Frappe that already addresses this requirement. If so, guidance on how to better integrate or utilize existing functionalities would be greatly appreciated.

Use Case

Currently, when developers need to dynamically fetch documents, they have to manually pass the Doctype name as a string, which can lead to errors if there are changes in the Doctype name or if the name is misspelled. This feature aims to eliminate such issues by allowing the following type-safe method of fetching documents:

from typing import TypeVar, Type
from frappe.model.document import Document

T = TypeVar("T", bound=Document)

def get_doc_typed(cls: Type[T], name: str) -> T:
    doctype_name = cls.get_doctype_name()
    return frappe.get_doc(doctype_name, name)


# example:
from frappe.core.doctype.user_group.user_group import UserGroup
my_group = get_doc_typed(UserGroup, "Example")  # type of my_group is UserGroup

@KlausH09 KlausH09 requested a review from a team as a code owner May 11, 2024 13:08
@KlausH09 KlausH09 requested review from ankush and removed request for a team May 11, 2024 13:08
@github-actions github-actions bot added the add-test-cases Add test case to validate fix or enhancement label May 11, 2024
@ankush
Copy link
Member

ankush commented May 11, 2024

Merging this might be better and more pythonic: #13223

from frappe.core.doctype.user_group.user_group import UserGroup
my_group = UserGroup("Example")

While I've given up on this being the default way to write code, offering it as an option seems fine 😄

@KlausH09
Copy link
Contributor Author

Thank you @ankush for reviewing my pull request and for pointing out alternative #13223. I appreciate the suggestion to use object instantiation directly for loading doctypes. However, I have some concerns about adopting this approach as a standard practice, particularly around the use of the __init__ method for this purpose.

Using the __init__ method to load data from the database can potentially lead to less clear and predictable code. Typically, constructors (__init__ methods) are used for initializing new objects, not for fetching existing data from a database. Instead, a class method, like get_doc, that explicitly handles database operations, might provide clearer semantics.

But the primary intention behind my pull request was to offer developers a straightforward way to obtain the Doctype name, enhancing the flexibility in how they might choose to implement features like those proposed in #13223 or others.

If this approach aligns with the project's goals, I'm more than happy to assist further, perhaps by updating the auto-generated code for doctypes to include this new method. Please let me know if there's anything specific you would like me to address or any other contributions I can make to help integrate this feature into the codebase effectively.

@Mutantpenguin
Copy link
Contributor

Mutantpenguin commented May 13, 2024

I am with @KlausH09 so as to not abuse the constructor for fetching data.

Let me throw another alternative into the ring:

UserGroup.get("id_here")
UserGroup.new()
UserGroup.delete("id_here")

@ankush
Copy link
Member

ankush commented May 13, 2024

Constructor already does this 😄 It's just that almost no one knows or uses it.

Try this:

from frappe.core.doctype.user.user import User
user = User("User", "Administrator")

@Mutantpenguin
Copy link
Contributor

Oh boy. I don't think this should be further brought forward. ^^

@KlausH09
Copy link
Contributor Author

The primary intention behind my pull request was to offer developers a straightforward way to obtain the Doctype name. Please take a look at the file changes!

I have only given theget_doc_typed function as an example of how to use this feature. And the proposed class methods from @Mutantpenguin are also just another use case. But this can all be discussed and implemented in a new PR.

So @ankush, is there anything I can do to get my PR accepted? For example, does it make sense for me to update the auto-generated code of the existing doctypes?

@ankush
Copy link
Member

ankush commented May 13, 2024

TBH I don't like this API as of now so I'll pass on this PR.

Importing a class and using another function to get typed document doesn't seem elegant to me. It should be done using the same class only.

Maybe another namespace is required like Django Class.objects.get(id=id)

@ankush ankush closed this May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add-test-cases Add test case to validate fix or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants