1

Django ミックスインは

「オブジェクト」を継承しますが、私の問題に対する代替ソリューションが見つかりません:(

質問をできるだけ簡単にするために、、、

ビュー.py

class JSONResponseMixin(object):
    def render_to_response(self, context):
        "Returns a JSON response containing 'context' as payload"
        return self.get_json_response(self.convert_context_to_json(context))

    def get_json_response(self, content, **httpresponse_kwargs):
        "Construct an `HttpResponse` object."
        return http.HttpResponse(content,
                                 content_type='application/json',
                                 **httpresponse_kwargs)

    def convert_context_to_json(self, context):
        "Convert the context dictionary into a JSON object"
        # Note: This is *EXTREMELY* naive; in reality, you'll need
        # to do much more complex handling to ensure that arbitrary
        # objects -- such as Django model instances or querysets
        # -- can be serialized as JSON.
        return json.dumps(context)


class HandlingAJAXPostMixin(JSONResponseMixin):
    def post(self, request, *args, **kwargs):
        .....
        data = {'somedata': somedata}

        return JSONResponseMixin.render_json_response(data)


class UserDetailView(HandlingAJAXPostMixin, DetailView):
    model = MyUser
    .....





したがって、私が抱えている問題は、複数のビューの場合、同じJSON 応答 で「投稿」要求に応答したいということです 。そのため、

他のビューで再利用できるように、HandlingAJAXPostMixin を定義しました。HandlingAJAXPostMixin は JSON 応答を返すため

、JSONResponseMixin で定義されている render_json_response メソッドが必要です。 これが、HandlingAJAXPostMixin がJSONResponseMixin を

継承するようにしている理由ですが、これは明らかに間違っているようです :(..提案はありますか ..?



ありがとう!!!

4

1 に答える 1

5

mixin が別の mixin を継承することは完全に有効です。実際、これは Django のより高度な mixin のほとんどが作成される方法です。

ただし、ミックスインの考え方は、他のクラスと一緒に完全で使用可能なクラスを構築する再利用可能なパーツであるということです。現時点では、JSONResponseMixin継承元ではない別のクラスであるか、メソッドがモジュール全体のメソッドである可能性があります。それは間違いなく機能し、何も問題はありませんが、それは mixin の考え方ではありません。

Django のBaseDetailViewを見ると、次のget()メソッドが表示されます。

def get(self, request, *args, **kwargs):
    self.object = self.get_object()
    context = self.get_context_data(object=self.object)
    return self.render_to_response(context)

get_object()get_context_data()は のサブクラスで定義されていますBaseDetailViewが、render_to_response()そうではありません。ミックスインが、そのスーパークラスが定義していないメソッドに依存することは問題ありません。これにより、継承元のさまざまなクラスがBaseDetailView独自の実装を提供できるようになりrender_to_response()ます。ただし、現在、Django にはサブクラスが 1 つしかありません。

ただし、ロジックは、ミックスインが提供する小さくて再利用可能なメソッドに可能な限り委譲されます。それがあなたが目指したいものです。If/else ロジックは可能な限り回避されます。Django のデフォルト ビューの最も高度なロジックは次のとおりです。

if form.is_valid(): 
    return self.form_valid(form) 
else: 
    return self.form_invalid(form)

CreateViewそのため、とのような非常によく似たビューUpdateViewは、実際には 2 つの別個のビューですが、追加の if/else ロジックを使用して簡単に単一のビューにすることができます。唯一の違いは、それがCreateView行うことです。self.object = NoneUpdateViewself.object = self.get_object()

現在、 の結果を返すメソッドをDetailView定義するを使用しています。ただし、テンプレート ベースの HTML 応答ではなく、JSON 応答を返すようにオーバーライドします。何を使用しないか ( ) の mixin を使用しており、その動作をオーバーライドして、やりたくないことを行うようにしています。ビューにやりたいことをさせるためだけです。より良いアイデアは、単一のオブジェクトに基づいて JSON 応答を提供することが唯一の仕事であるという代替案を作成することです。これを行うには、に似た を作成し、必要なすべての mixin を 1 つのオブジェクトに結合するクラスを作成します。get()self.render_to_response()render_to_response()SingleObjectTemplateResponseMixinDetailViewSingleObjectJSONResponseMixinSingleObjectTemplateResponseMixinJSONDetailView

class SingleObjectJSONResponseMixin(object):
    def to_json(context):
        return json.dumps(context)

    def render_to_response(context, **httpresponse_kwargs):
        return HttpResponse(self.to_json(context),
                            context_type='application/json',
                            **httpresponse_kwargs)

class BaseJSONDetailView(SingleObjectMixin, View):
    # if you want to do the same for get, inherit just from BaseDetailView
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        return render_to_response(context)

class JSONDetailView(SingleObjectJSONResponseMixin, BaseJSONDetailView):
    """ 
    Return JSON detail data of a single object.
    """

これは、Django が提供するBaseDetailViewおよび とほぼ同じであることに注意してください。SingleObjectTemplateResponseMixin違いは、post()メソッドを定義することと、完全なテンプレート レンダリングではなく、コンテキスト データを JSON に変換するだけでレンダリングがはるかに単純になることです。ただし、ロジックは意図的に可能な限りシンプルに保ち、相互に依存しないメソッドは可能な限り分離します。このように、SingleObjectJSONResponseMixinたとえば と混合しBaseUpdateViewて、AJAX/JSON ベースの を簡単に作成できますUpdateViewto_json()サブクラスは、特定のデータ構造を提供するためにオーバーライドするなど、ミックスインのさまざまな部分を簡単にオーバーライドできます。レンダリング ロジックは、それが属する場所です ( render_to_response())。

特定のモデルを作成するために必要なのJSONDetailViewは、サブクラス化して使用するモデルを定義することだけです。

class UserJSONDetailView(JSONDetailView):
    model = MyUser
于 2013-08-10T13:51:25.287 に答える