수색…


비고

CBV를 사용할 때 종종 각 일반 클래스에 대해 덮어 쓸 수있는 방법을 정확히 알아야합니다. 장고 문서의 페이지 는 모든 일반 클래스를 그 모든 메소드를 평평하게하고, 우리가 사용할 수있는 클래스 속성을 나열합니다.

또한 Classy Class Based View 웹 사이트는 멋진 대화 형 인터페이스로 동일한 정보를 제공합니다.

클래스 기반 뷰

수업 기반보기를 사용하면 조회수를 특별하게 만드는 요소에 집중할 수 있습니다.

정적 페이지 정보는 사용 된 템플릿을 제외하고는 특별한 것이 없습니다. TemplateView를 사용하십시오! 템플릿 이름을 설정하기 만하면됩니다. 작업 완료. 다음 것.

views.py

from django.views.generic import TemplateView


class AboutView(TemplateView):
    template_name = "about.html"

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url('^about/', views.AboutView.as_view(), name='about'),
]

URL에서 AboutView 를 직접 사용하지 않는 AboutView 하십시오. 왜냐하면 callable이 예상되고 정확히 as_view() 반환하기 때문입니다.

컨텍스트 데이터

때로는 템플릿에 좀 더 많은 정보가 필요합니다. 예를 들어, 사용자의 페이지 헤더에 로그 아웃 링크 옆에 자신의 프로필에 대한 링크가 표시되도록하고 싶습니다. 이러한 경우 get_context_data 메소드를 사용하십시오.

views.py

class BookView(DetailView):
    template_name = "book.html"

    def get_context_data(self, **kwargs)
        """ get_context_data let you fill the template context """
        context = super(BookView, self).get_context_data(**kwargs)
        # Get Related publishers
        context['publishers'] = self.object.publishers.filter(is_active=True)
        return context

수퍼 클래스에서 get_context_data 메서드를 호출하면 기본 컨텍스트 인스턴스가 반환됩니다. 이 사전에 추가 한 항목은 템플리트에서 사용할 수 있습니다.

book.html

<h3>Active publishers</h3>
<ul>
  {% for publisher in publishers %}
    <li>{{ publisher.name }}</li>
  {% endfor %}
</ul>

목록 및 세부 정보보기

템플릿 뷰는 정적 페이지에서는 괜찮으며 get_context_data 로 모든 것을 사용할 수는 있지만 함수를 뷰로 사용하는 것보다 간신히 낫습니다.

ListViewDetailView 입력

app / models.py

from django.db import models

class Pokemon(models.Model):
    name = models.CharField(max_length=24)
    species = models.CharField(max_length=48)
    slug = models.CharField(max_length=48)

app / views.py

from django.views.generic import ListView, DetailView
from .models import Pokemon


class PokedexView(ListView):
    """ Provide a list of Pokemon objects """
    model = Pokemon
    paginate_by = 25

class PokemonView(DetailView):
    model = Pokemon

그것이 모델의 모든 객체와 단수 항목의 뷰를 나열하는 뷰를 생성하는 데 필요한 모든 것입니다. 목록은 심지어 페이지가 매겨집니다. 특정 항목을 원할 경우 template_name 을 제공 할 수 있습니다. 기본적으로 모델 이름에서 생성됩니다.

app / templates / app / pokemon_list.html

<!DOCTYPE html>
<title>Pokedex</title>
<ul>{% for pokemon in pokemon_list %}
    <li><a href="{% url "app:pokemon" pokemon.pk %}">{{ pokemon.name }}</a>
        &ndash; {{ pokemon.species }}
</ul>

컨텍스트는 두 개의 이름 인 object_list 아래에있는 개체 목록과 모델 이름의 두 번째 빌드 (여기 pokemon_list . 목록을 페이지 매김 한 경우 다음 링크와 이전 링크도 처리해야합니다. Paginator 객체는이를 지원할 수 있으며 컨텍스트 데이터에서도 사용할 수 있습니다.

app / templates / app / pokemon_detail.html

<!DOCTYPE html>
<title>Pokemon {{ pokemon.name }}</title>
<h1>{{ pokemon.name }}</h1>
<h2>{{ pokemon.species }} </h2>

앞에서와 마찬가지로 컨텍스트는 모델 객체에서 이름 objectpokemon 으로 채워지며 두 번째 모델은 모델 이름에서 파생됩니다.

app / urls.py

from django.conf.urls import url
from . import views

app_name = 'app'
urlpatterns = [
    url(r'^pokemon/$', views.PokedexView.as_view(), name='pokedex'),
    url(r'^pokemon/(?P<pk>\d+)/$', views.PokemonView.as_view(), name='pokemon'),
]

이 스 니펫에서 기본보기를 사용하여 세부 정보보기 URL이 작성됩니다. 인수로서 슬러그를 사용하는 것도 가능합니다. 이렇게하면 더 쉽게 기억할 수있는 멋진 URL이 제공됩니다. 그러나 모델에 slug라는 필드가 있어야합니다.

url(r'^pokemon/(?P<slug>[A-Za-z0-9_-]+)/$', views.PokemonView.as_view(), name='pokemon'),

라는 필드 경우 slug 존재하지 않습니다, 당신은 사용할 수 있습니다 slug_field 에 설정 DetailView 다른 필드를 가리 키도록.

페이지 매김의 경우 페이지 가져 오기 매개 변수를 사용하거나 URL에 직접 페이지를 넣으십시오.

양식 및 개체 생성

객체를 생성하기위한 뷰를 작성하는 것은 상당히 지루할 수 있습니다. 양식을 표시해야하고 유효성을 검사해야하며 항목을 저장하거나 오류가있는 양식을 반환해야합니다. 일반적인 편집보기 중 하나를 사용하지 않는 한.

app / views.py

from django.core.urlresolvers import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Pokemon


class PokemonCreate(CreateView):
    model = Pokemon
    fields = ['name', 'species']


class PokemonUpdate(UpdateView):
    model = Pokemon
    fields = ['name', 'species']


class PokemonDelete(DeleteView):
    model = Pokemon
    success_url = reverse_lazy('pokedex')

CreateViewUpdateView 두 가지 속성, 요구 한 modelfields . 기본적으로 '_form'접미사가 붙은 모델 이름을 기반으로 템플릿 이름을 사용합니다. template_name_suffix 속성을 사용하여 접미어 만 변경할 수 있습니다. DeleteView는 개체를 삭제하기 전에 확인 메시지를 표시합니다.

UpdateViewDeleteView 는 모두 객체에서 가져와야합니다. 이들은 DetailView 와 동일한 메소드를 사용하여 url에서 변수를 추출하고 객체 필드를 일치시킵니다.

app / templates / app / pokemon_form.html (추출)

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>

form 에는 필요한 모든 필드가있는 양식이 들어 있습니다. 여기서는 as_p 때문에 각 필드에 단락과 함께 표시됩니다.

app / templates / app / pokemon_confirm_delete.html (추출)

<form action="" method="post">
    {% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    <input type="submit" value="Confirm" />
</form>

요청 위조에 대한 django 보호 때문에 csrf_token 태그가 필요합니다. 양식을 표시하는 URL이 삭제 / 저장을 처리하는 URL과 동일하기 때문에 속성 조치는 비어 있습니다.

목록 및 세부 예제와 동일하게 사용하는 경우 두 가지 문제가 모델에 남아 있습니다. 첫째, 생성 및 업데이트는 누락 된 리디렉션 URL에 대해 불만을 제기합니다. 그것은 포켓몬 모델에 get_absolute_url 을 추가하여 해결할 수 있습니다. 두 번째 문제는 의미있는 정보를 표시하지 않는 삭제 확인입니다. 이를 해결하는 가장 쉬운 방법은 문자열 표현을 추가하는 것입니다.

app / models.py

from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible


@python_2_unicode_compatible
class Pokemon(models.Model):
    name = models.CharField(max_length=24)
    species = models.CharField(max_length=48)

    def get_absolute_url(self):
        return reverse('app:pokemon', kwargs={'pk':self.pk})

    def __str__(self):
        return self.name

클래스 데코레이터는 모든 것이 파이썬 2에서 원활하게 작동하는지 확인합니다.

최소 예제

views.py :

from django.http import HttpResponse
from django.views.generic import View

class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse('result')

urls.py :

from django.conf.urls import url
from myapp.views import MyView

urlpatterns = [
    url(r'^about/$', MyView.as_view()),
]

Django 문서에 대해 자세히 알아보기»

Django 클래스 기반 뷰 : CreateView 예제

클래스 기반 일반 뷰를 사용하면 모델에서 CRUD 뷰를 매우 간단하고 쉽게 만들 수 있습니다. 종종 내장 된 장고 관리자가 충분하지 않거나 바람직하지 않으며 우리 자신의 CRUD 뷰를 롤업해야합니다. CBV는 이러한 경우에 매우 유용 할 수 있습니다.

CreateView 클래스는 모델, 사용할 필드 및 성공 URL 등 3 가지를 필요로합니다.

예:

from django.views.generic import CreateView 
from .models import Campaign

class CampaignCreateView(CreateView):
    model = Campaign
    fields = ('title', 'description')
    
    success_url = "/campaigns/list"

생성이 성공하면 사용자는 success_url 로 리디렉션됩니다. 대신 get_success_url 메소드를 정의하고 reverse 또는 reverse_lazy 를 사용하여 성공 URL을 얻을 수도 있습니다.

이제이 뷰에 대한 템플리트를 작성해야합니다. 템플릿의 이름은 <app name>/<model name>_form.html 형식 <app name>/<model name>_form.html 합니다. 모델 이름은 하단 대문자 여야합니다. 예를 들어 내 앱 이름이 dashboard 인 경우 위의 작성보기에서 dashboard/campaign_form.html 이라는 템플릿을 만들어야합니다.

템플릿에서 form 변수는 form 을 포함합니다. 다음은 템플릿의 샘플 코드입니다.

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>            

이제 URL 패턴에보기를 추가 할 차례입니다.

url('^campaign/new/$', CampaignCreateView.as_view(), name='campaign_new'),

URL을 방문하면 선택한 필드가있는 양식이 표시됩니다. 제출할 때 데이터로 모델의 새 인스턴스를 만들고 저장합니다. 성공하면 사용자는 성공 URL로 리디렉션됩니다. 오류가 발생하면 양식이 오류 메시지와 함께 다시 표시됩니다.

하나의보기, 여러 양식

하나의 장고 (Django) 뷰에서 여러 폼을 사용하는 빠른 예제가있다.

from django.contrib import messages
from django.views.generic import TemplateView

from .forms import AddPostForm, AddCommentForm
from .models import Comment

class AddCommentView(TemplateView):

    post_form_class = AddPostForm
    comment_form_class = AddCommentForm
    template_name = 'blog/post.html'

    def post(self, request):
        post_data = request.POST or None
        post_form = self.post_form_class(post_data, prefix='post')
        comment_form = self.comment_form_class(post_data, prefix='comment')

        context = self.get_context_data(post_form=post_form,
                                        comment_form=comment_form)

        if post_form.is_valid():
            self.form_save(post_form)
        if comment_form.is_valid():
            self.form_save(comment_form)

        return self.render_to_response(context)     

    def form_save(self, form):
        obj = form.save()
        messages.success(self.request, "{} saved successfully".format(obj))
        return obj

    def get(self, request, *args, **kwargs):
        return self.post(request, *args, **kwargs)


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow