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

feature request: class-based views support. #54

Open
Lazerbeak12345 opened this issue Dec 6, 2024 · 9 comments
Open

feature request: class-based views support. #54

Lazerbeak12345 opened this issue Dec 6, 2024 · 9 comments

Comments

@Lazerbeak12345
Copy link

Lazerbeak12345 commented Dec 6, 2024

for some things, such as integration with DjangoRESTFramework, it would be nice if, in addition to the @inertia('ClientSidePage') decorator, support for class based views could be added.

My recommendation is to provide a mix-in (as shown here), which might be used like this:

from django.views import View
from inertia import InertiaMixin


class AsdfView(InertiaMixin, View):
    component = "Asdf"

    def get(self, request):
        return { "message": "asdf" }

If you're careful, then the mixin could function by internally decorating each method function with @inertia("Asdf") - though bear in mind these method functions take the View instance as the first arg, so chaperoning the mixin is necessary.

@Lazerbeak12345
Copy link
Author

Lazerbeak12345 commented Dec 7, 2024

from django.views import View
from inertia import inertia

@method_decorator(inertia("Asdf"), name='dispatch')
class AsdfView(View):
    def get(self, request):
        return { "message": "asdf" }

This works instead. :/ my bad guys lol

EDIT: this is untested, though when I tried it on APIView from Django REST API, it didn't work.

@Lazerbeak12345
Copy link
Author

Lazerbeak12345 commented Dec 12, 2024

also when that doesn't work (due to the dispatcher expecting response objects returned from methods in some contexts), you can still decorate the methods directly

from django.views import View
from inertia import inertia

class AsdfView(View):
    @method_decorator(inertia("Asdf"))
    def get(self, request):
        return { "message": "asdf" }

EDIT: I have tested this, and it works, even with Django REST API's APIVew

@Lazerbeak12345
Copy link
Author

Considering that the latter be inconvenient, perhaps a mixin to make this easier would still be a good idea.

@BrandonShar
Copy link
Collaborator

I think a mixin for class based views makes sense, but I don't have enough DRF experience to know offhand what it would look like. I definitely take a look when I have some time, but if you already have an idea about how it would structured that would be great to discuss here.

@Lazerbeak12345
Copy link
Author

Lazerbeak12345 commented Dec 28, 2024

The generic way to do this would be to add middware to Django's dispatch function, though that doesn't seem to work in all cases, as the dict type Inertia allows returned from views isn't technically a Response object, which some Django libraries expect. We'd have to convert it into an inertia response before they see it (which is why without mixins manually decorating functions works but decorating the class doesn't)

I wrote some experimental code a bit ago to add specific support for DRF to django-inertia, but considering that it must import things from DRF, I'm not sure if that code should go in this package, or in a different package.

Full DRF support would mean that inertia views using DRF for (de)serialization and validation would have to catch DRF errors (they all inherit from one abstract class) and provide an API so they can be in shared, and likely boxed, component props. My code didn't even provide a way to use DRF's ViewSet feature, or their extension to Django's permission system. Then comes the special case of replying with inertia for HTML mimetype requests and inertia requests, but falling back to DRF otherwise (for public APIs, or xhr requests from the client that we don't want to change the client's endpoint)

TLDR: while DRF should be kept in mind, specific support for DRF would be very complicated.

@Lazerbeak12345
Copy link
Author

Also, when digging around in DRF and Django source, I remember seeing a class property that is an enumeration of the available http method methods on the implementation. If that's part of Django itself, iterating over that list and internally using the decorator I demoed a few comments ago would work in all cases.

@BrandonShar
Copy link
Collaborator

hmm interesting. I would normally say it's a separate library in cases like this, but DRF is so popular that I kind of think it should go in the main adapter if it can. I'll spin up a DRF repo this weekend and poke around a bit! The class property you mentioned could be awesome if we can detect the presence of DRF easily.

@Lazerbeak12345
Copy link
Author

Lazerbeak12345 commented Jan 5, 2025

Unfortunately, whatever is done in the mixin, the api's a bit leaky anyway.

Some decorators mandate method returns to be a response instance. Documentation would have to provide a workaround of chaining decorators manually. There should be no problem with chaining multiple inertia decorators, since all it does is convert from dict to response and pass everything else through.

@Lazerbeak12345
Copy link
Author

oh! Also if DRF support is added somehow, the integration should definitely be added here. It'd be great for SEO, I bet.

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

No branches or pull requests

2 participants