Question: I have created some forms using class based views, now I like to add them to the Django Admin site. I have only found this [link](http://patrick.arminio.info/additional-admin-views/) which describes adding normal views to the Admin site.

Answer: 
For a full integration with Django admin templates, you can pass the model admin as an extra argument to the class based view, then use it to add some sugar to the context:

file admin.py:

```
from django.contrib import admin
from .models import MyModel
from .views import ProcessObjectView

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):

    def get_urls(self):
        info = self.model._meta.app_label, self.model._meta.model_name
        urls = super().get_urls()
        my_urls = patterns('',
            url(r'^(?P<object_id>.*)/process/$',
                self.admin_site.admin_view(ProcessObjectView.as_view()),
                {'model_admin': self, },
                name="%s_%s_process" % info),
        )
        return my_urls + urls

```

file views.py

```
from django.contrib.auth import get_permission_codename

class ProcessObjectView(UpdateView):

    model = MyModel
    pk_url_kwarg = "object_id"
    fields = [... ]
    template_name = 'admin/backend/mymodel/process_object.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # see http://www.slideshare.net/lincolnloop/customizing-the-django-admin
        model_admin = self.kwargs['model_admin']
        opts = model_admin.model._meta
        admin_site = model_admin.admin_site
        has_perm = self.request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts))
        context.update({
            'admin_site': admin_site.name,
            'title': 'Process: ' + str(self.get_object()),
            'opts': opts,
            'app_label': opts.app_label,
            'has_chage_permission': has_perm,
        })

        return context

```

file process\_object.html:

```
{% extends "admin/change_form.html" %}
{% load i18n utils_tags %}

{% block content %}
...

```
You can pass the class based view's `as_view` directly, without need of having a variable like `awesome_book_view` as suggested by another answer: 

Example:

in `admin.py` I have:

```
class EmailAdmin(admin.ModelAdmin):

    def get_urls(self):
        urls = super(EmailAdmin, self).get_urls()
        my_urls = [
            url(r'^send_email/$',
                self.admin_site.admin_view(SendEmailAdminView.as_view())),
        ]
        return my_urls + urls

admin.site.register(Email, EmailAdmin)

```

in `views.py` I have:

```
class SendEmailAdminView(View):

    def get(self, request):
        pass

    def post(self, request):
        pass

```

I have removed most of the code for brevity and have kept only relevant part. You can see the full [code here](https://github.com/avinassh/nightreads/tree/master/nightreads/emails).