使用基于类的视图来处理信息?

发布于 2024-11-30 13:03:56 字数 1588 浏览 3 评论 0原文

我一直在尝试 Django 的基于类的视图,并尝试编写一个简单的基于类的视图来处理 request 中的某些信息,以便“处理程序”方法可以使用处理后的信息。

我似乎没有完全理解文档所说的内容,并且不确定这是否应该是 Mixin、通用视图还是其他东西。我正在考虑创建一个这样的类:

class MyNewGenericView(View):

    redirect_on_error = 'home'
    error_message = 'There was an error doing XYZ'

    def dispatch(self, request, *args, **kwargs):
        try:
            self.process_information(request)
            # self.process_information2(request)
            # self.process_information3(request)
            # etc...
        except ValueError:
            messages.error(request, self.error_message)
            return redirect(self.redirect_on_error)
        return super(MyNewGenericView, self).dispatch(request, *args, **kwargs)

    def process_information(self, request):
        # Use get/post information and process it using
        # different models, APIs, etc.
        self.useful_information1 = 'abc'
        self.useful_information2 = 'xyz'

    def get_extra_info(self):
        # Get some extra information on something
        return {'foo':'bar'}

这将允许某人编写如下视图:

class MyViewDoesRealWork(MyNewGenericView):
    def get(self, request, some_info):
        return render(request, 'some_template.html',
            {'info':self.useful_information1})

    def post(self, request, some_info):
        # Store some information, maybe using get_extra_info
        return render(request, 'some_template.html',
            {'info':self.useful_information1})

上面的代码是正确的方法吗?有没有更简单/更好的方法来做到这一点?这是否会阻止上述功能在另一个通用视图(例如内置通用视图)中使用?

I've been experimenting with Django's Class Based Views and am trying to write a simple class based view that processes certain information in request so that the processed information can be used by the "handler" method.

I don't seem to have fully understood what the docs say and am unsure of whether this should be a Mixin, a generic view or something else. I'm thinking of making a class like this:

class MyNewGenericView(View):

    redirect_on_error = 'home'
    error_message = 'There was an error doing XYZ'

    def dispatch(self, request, *args, **kwargs):
        try:
            self.process_information(request)
            # self.process_information2(request)
            # self.process_information3(request)
            # etc...
        except ValueError:
            messages.error(request, self.error_message)
            return redirect(self.redirect_on_error)
        return super(MyNewGenericView, self).dispatch(request, *args, **kwargs)

    def process_information(self, request):
        # Use get/post information and process it using
        # different models, APIs, etc.
        self.useful_information1 = 'abc'
        self.useful_information2 = 'xyz'

    def get_extra_info(self):
        # Get some extra information on something
        return {'foo':'bar'}

This will allow someone to write a view like:

class MyViewDoesRealWork(MyNewGenericView):
    def get(self, request, some_info):
        return render(request, 'some_template.html',
            {'info':self.useful_information1})

    def post(self, request, some_info):
        # Store some information, maybe using get_extra_info
        return render(request, 'some_template.html',
            {'info':self.useful_information1})

Is the above code the right way to go? Is there any simpler/better way of doing this? Will this prevent the above functionalities from being used in another generic view (e.g. a built-in generic view)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森末i 2024-12-07 13:03:56

看来我只是问了一个愚蠢的问题。

这可以通过创建一个处理该信息的类来轻松实现:

class ProcessFooInformation(object):
    def __init__(self, request):
        self.request = request
    @property
    def bar(self):
        baz = self.request.GET.get('baz', '')
        # do something cool to baz and store it in foobar
        return foobar
    # etc...

然后使用旧式函数视图或新的基于类的视图:

def my_view(request):
    foo = ProcessFooInformation(request)
    # use foo in whatever way and return a response
    return render(request, 'foobar.html', {'foo':foo})

我还通过使用属性的惰性求值来提高效率。

我改编了惰性属性评估配方的想法以及要写的​​评论包装器:

def lazy_prop(func):
    def wrap(self, *args, **kwargs):
        if not func.__name__ in self.__dict__:
            self.__dict__[func.__name__] = func(self, *args, **kwargs)
        return self.__dict__[func.__name__]
    return property(wrap)

每个实例仅计算一次包装方法的值,并在后续调用中使用存储的值。如果房产评估缓慢,这很有用。

It seems I just asked a stupid question.

This can easily be achieved by making a class that processes that information:

class ProcessFooInformation(object):
    def __init__(self, request):
        self.request = request
    @property
    def bar(self):
        baz = self.request.GET.get('baz', '')
        # do something cool to baz and store it in foobar
        return foobar
    # etc...

Then using old style function views or new class-based views:

def my_view(request):
    foo = ProcessFooInformation(request)
    # use foo in whatever way and return a response
    return render(request, 'foobar.html', {'foo':foo})

I also made this more efficient by using lazy evaluation of properties.

I adapted ideas from the lazy property evaluation recipe and the comments to write a wrapper:

def lazy_prop(func):
    def wrap(self, *args, **kwargs):
        if not func.__name__ in self.__dict__:
            self.__dict__[func.__name__] = func(self, *args, **kwargs)
        return self.__dict__[func.__name__]
    return property(wrap)

This evaluates the value of the wrapped method only once per instance and uses a stored value on subsequent calls. This is useful if the property evaluates slowly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文