如何编写可与多种模型一起使用的urls和视图?
假设我的models.py名中有3个型号:自行车、滑板车、移动
现在,对于通用视图的Bike模型,我们需要:
1]5 views : ListView, DetailView, CreateView, UpdateView, DeleteView
2]5 urls : one for each 5 views we need 1 url
3]4 html files are required :
bike_list.html : for ListView
bike_detail.html : for DetailView
bike_form.html : for CreateView and UpdateView
conifirm_delete_view.html : for DeleteView现在,对于通用视图的Scooty模型,我们需要:
1]again 5 views : ListView, DetailView, CreateView, UpdateView, DeleteView
2]again 5 urls : one for each 5 views we need 1 url
3]4 html files are required :
scooty_list.html : for ListView
scooty_detail.html : for DetailView
scooty_form.html : for CreateView and UpdateView
conifirm_delete_view.html : for DeleteView对于另一个模型,我需要:5多个视图,5多个网址,4多个html文件。
但是,如果您编写通用视图并在URL中传递模型的名称,模型本身就会在视图中获取,并将其传递给通用视图。
因此,相同的5个视图,5个urls和4个html文件可以用于许多型号。
发布于 2020-07-21 21:40:57
GitHub Repo中的完整代码
https://github.com/punisher21maximum/Blog/tree/master/Minimise_Django_Codeurls.py
from django.urls import path
from .views import (
#subcat Views
SubcatListView,
SubcatDetailView,
SubcatCreateView,
SubcatUpdateView,
SubcatDeleteView,
)
from . import views
urlpatterns = [
#subcat
path('<str:model>/new/', SubcatCreateView.as_view(), name='subcat-create'),
path('<str:model>/', SubcatListView.as_view(), name='subcat-list'),
path('<str:model>/<int:pk>/', SubcatDetailView.as_view(), name='subcat-detail'),
path('<str:model>/<int:pk>/update/', SubcatUpdateView.as_view(), name='subcat-update'),
path('<str:model>/<int:pk>/delete/', SubcatDeleteView.as_view(), name='subcat-delete'),
]views.py
from django.urls import reverse_lazy
from .models import Post, Bike, Scooty, Bicycle, Mobile
model_dict = {
"Post":Post,
"Bike":Bike,
"Scooty":Scooty,
"Bicycle":Bicycle,
"Mobile":Mobile
}
#get my fields
def my_get_model_fields(model):
all_f = [field.name for field in model._meta.get_fields()]
rf = ['id', 'date_posted']
all_f.remove('author')
for f in all_f:
if f in rf or f.endswith('_ptr'):
all_f.remove(f)
return all_f
"""subcat view"""
#ListView
class SubcatListView(ListView):
template_name = 'blog/subcat_list.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 3
"""overriding "dispatch" func to set model passed as arg in URL"""
def dispatch(self, request, *args, **kwargs):
self.model = model_dict[ kwargs.get('model', None) ]
return super(SubcatListView, self).dispatch(request, *args, **kwargs)
""" "get_queryset" also Required to override model name """
def get_queryset(self):
return self.model.objects.filter()
def get_context_data(self, **kwargs):
"""override "get_context_data" to pass model_name to subcat_list.html"""
context = super().get_context_data(**kwargs)
context['class_name'] = self.model._meta.model_name.title() # kwargs.get('model', None)
return context
#DetailView
class SubcatDetailView(DetailView):
"""overriding "dispatch" func to set model passed as arg in URL"""
# template_name = <app>/<model>_<viewtype>.html
context_object_name = 'post'
template_name = 'blog/subcat_detail.html'
def dispatch(self, request, *args, **kwargs):
self.model = model_dict[ kwargs.get('model', None) ]
return super(SubcatDetailView, self).dispatch(request, *args, **kwargs)
def get_queryset(self):
return self.model.objects.filter()
def get_context_data(self, **kwargs):
"""override "get_context_data" to pass model_name to subcat_list.html"""
context = super().get_context_data(**kwargs)
context['class_name'] = self.model._meta.model_name.title() # kwargs.get('model', None)
return context
#CreateView
class SubcatCreateView(LoginRequiredMixin, CreateView):
# model = Bike
# fields = my_get_model_fields(Bike)
template_name = 'blog/subcat_form.html'
def form_valid(self, form):
"""check form author and current logged in user is same"""
form.instance.author = self.request.user
return super().form_valid(form)
def dispatch(self, request, *args, **kwargs):
"""overriding "dispatch" func to set model passed as arg in URL"""
self.model = model_dict[ kwargs.get('model', None) ]
return super(SubcatCreateView, self).dispatch(request, *args, **kwargs)
def get_form_class(self):
"""overriding "get_form_class" func to get fields for model passed in URL"""
self.fields = my_get_model_fields(model_dict[self.model._meta.model_name.title()])
return super(SubcatCreateView, self).get_form_class()
#UpdateView
class SubcatUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
template_name = 'blog/subcat_form.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def dispatch(self, request, *args, **kwargs):
"""overriding "dispatch" func to set model passed as arg in URL"""
self.model = model_dict[ kwargs.get('model', None) ]
return super(SubcatUpdateView, self).dispatch(request, *args, **kwargs)
def get_form_class(self):
"""overriding "get_form_class" func to get fields for model passed in URL"""
self.fields = my_get_model_fields(model_dict[self.model._meta.model_name.title()])
return super(SubcatUpdateView, self).get_form_class()
#DeleteView
class SubcatDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
template_name = 'blog/post_confirm_delete.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def dispatch(self, request, *args, **kwargs):#model
"""overriding "dispatch" func to set model passed as arg in URL"""
self.model = model_dict[ kwargs.get('model', None) ]
return super(SubcatDeleteView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):#class_name
"""override "get_context_data" to pass model_name to subcat_list.html"""
context = super().get_context_data(**kwargs)
context['class_name'] = self.model._meta.model_name.title() # kwargs.get('model', None)
return context
def get_success_url(self):
return reverse_lazy('subcat-list', kwargs={'model':self.model._meta.model_name.title()})subcat_list.html
{% if class_name == "Bike" %}
<a class="article-title" href="{% url 'subcat-detail' pk=post.id model='Bike' %}">
{% elif class_name == "Scooty" %}
<a class="article-title" href="{% url 'subcat-detail' pk=post.id model='Scooty' %}">
{% elif class_name == "Mobile" %}
<a class="article-title" href="{% url 'subcat-detail' pk=post.id model='Mobile' %}">
{% endif %}
<img class="d-block w-100" src="{{ post.img1.url }}" height="250px;" alt="First slide">
</a>
{% if class_name == "Bike" %}
{% include "blog/bike_list2.html" %}
{% elif class_name == "Scooty" %}
{% include "blog/scooty_list2.html" %}
{% elif class_name == "Mobile" %}
{% include "blog/mobile_list2.html" %}
{% endif %} subcat_detail.html
{% if object.author == user %}
<div>
<!-- update and delete -->
{% if class_name == "Bike" %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'subcat-update' pk=object.id model='Bike' %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'subcat-delete' pk=object.id model='Bike' %}">Delete</a>
{% elif class_name == "Scooty" %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'subcat-update' pk=object.id model='Scooty' %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'subcat-delete' pk=object.id model='Scooty' %}">Delete</a>
{% elif class_name == "Mobile" %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'subcat-update' pk=object.id model='Mobile' %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'subcat-delete' pk=object.id model='Mobile' %}">Delete</a>
{% endif %}
</div>
{% endif %}
<div style="font-size: 12px;">
{% if class_name == "Bike" %}
{% include "blog/bike_list2.html" %}
{% elif class_name == "Scooty" %}
{% include "blog/scooty_list2.html" %}
{% elif class_name == "Mobile" %}
{% include "blog/mobile_list2.html" %}
{% endif %}
</div>https://stackoverflow.com/questions/63015674
复制相似问题