Djangoにおける汎用ビュー简述-中文翻译

原文为日文，本文为翻译、摘抄。 --仅供自用
参照‘https://qiita.com/dai-takahashi/items/7d0187485cad4418c073’

通用View:为Model和Form提供既定参数，可以简化代码量。

### 书写方式： 

```views.py
from django.views.generic import TemplateView

class SampleTemplateView(TemplateView):
    template_name = "index.html"
```

```urls.py
from django.views.generic import TemplateView

class SampleTemplateView(TemplateView):
    template_name = "index.html"
```

### 基本传参：

```views.py
from django.views.generic import TemplateView

class SampleTemplate(TemplateView):
    template_name = "index.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs) # はじめに継承元のメソッドを呼び出す
        context["foo"] = "bar"
        return context
```

```index.html
<div class="sample">{{ foo }}</div>
```

### 全部View：
'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView',
'YearArchiveView', 'MonthArchiveView', 'WeekArchiveView', 'DayArchiveView',
'TodayArchiveView', 'DateDetailView', 'DetailView', 'FormView',
'CreateView', 'UpdateView', 'DeleteView', 'ListView', 'GenericViewError',

#### TemplateView：
必须指定Template

```views.py
from django.views.generic import TemplateView

class MyTemplateView(TemplateView):
    template_name = "index.html"  # 必须

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 一些命令
        return context
```

#### ListView：
用于显示列表

```views.py
from django.views.generic import ListView
from foo.model import MyModel

class MyListView(ListView):

    model = MyModel # 已做成的Model
    paginate_by = 10 # 按每页10条分割显示
    context_object_name = 'member_list' #给queryset命名，与object_list可同时使用

    def get_queryset(self, queryset=None):
        return MyModel.objects.all()[:10] # 用queryset分割

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**data) # 复写
        context["bar"] = OtherModel.objects.all()  # 从其他Model中取数据
        return context
```

```mymodel/mymodel_list.html
<ul>
  {% for item in object_list %} <!--MyModel中的数据-->
  <li>{{ item }}</li>
  {% endfor %}

  {% for item in member_list %} <!--MyModel中的数据-->
  <li>{{ item }}</li>
  {% endfor %}

  {% for item in bar %} <!--OtherModel中的数据-->
  <li>{{ item }}</li>
  {% endfor %}
</ul>
```

#### DetailView
用于详细内容画面
url中需要传递id等具体参数

```views.py
from django.views.generic import DetailView
from mymodel.model import MyModel

class MyDetailView(DetailView):
    model = MyModel
    template_name = 'detail.html'
    pk_url_kwarg = 'id'
    slug_field = "title" #自定义ModelField
    slug_url_kwarg = "pk" #自定义url.py中的参数
```

```urls.py
urlpatterns = [
    url('pages/<int:pk>', MyDetailView.as_view()),
]
```

#### CreateView・UpdateView
添加与更新记录

```views.py
from django.views.generic.edit import CreateView

class MyCreateView(CreateView):
    model = MyModel
    fields = ("name", "other",)  
# 直接写form，未定义的fields即使提交form也不会更新
```

```form.html
<form method="post">
    {% csrf_token %}
    <table>
        {{ form }} 
        <!-- 用<p>时：{{ form.as_p }} -->
    </table>
    <input type="submit">
</form>
```

用forms.py中写好的form：

```forms.py
from django import forms
from myapp.model import MyModel

 #具体参照form的写法
class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ("name", )
```

```views.py
from django.views.generic.edit import CreateView
from django.contrib import messages  # メッセージフレームワーク

from myapp.models import MyModel


class MyCreateView(CreateView):
    model = MyModel
    form_class = Form2 #使用的form
    success_url = reverse_lazy('app:画面名')
    #保存成功时画面跳转

    def form_valid(self, form):
        '''通过格式检查'''
        messages.success(self.request, "信息已保存")
        return super().form_valid(form)

    def form_invalid(self, form):
        '''未通过格式检查'''
        message.warning(self.request, "未保存")
        return super().form_invalid(form)
 #似乎有即使未通过检查也能暂存form等待修改的方法
```

在画面表示成功信息：

```form.html
{% if messages %}
<ul class="messages">
    {% for message in messages %}
        <li
        {% if message.tags %} class="{{ message.tags }}"
        {% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}
```

####DeleteView
删除记录用
默认temlplate为(AppName)/(AppName)_confirm_delete.html

```views.py
from django.views.generic.edit import DeleteView
from myapp.models import MyModel

class MyDeleteView(DeleteView):
    model = MyModel
```
此时会显示“是否确认删除”的确认画面
如果不想真的删除，只是delete_flag = on的话，可以重写delete方法


#### 共通項目
#####指定model：
model = MyModel
#####template中使用model中的内容：
{{ object }}
或者
{% for item in object_list %}
  {{ item }}
{% endfor %}

#####自定义model内容的变量名：
context_object_name = "my_object"

#####默认template名
(ModelName)/(ModelName)_(ViewName).html
例：
AppName：myapp
View种类：ListView

则默认template名为
  myapp/myapp_list.html

#####template名指定
template_name = "my_list_view.html"