Django DetailView + 显示另一个Model的相关记录
Django DetailView + show related record of another Model
我想return到用户相关记录。
有人可以帮助我吗?
我的部分观点
class UserProfileDetailView(DetailView):
model = get_user_model()
slug_field = "username"
template_name = "perfil.html"
def get_object(self, queryset=None):
user = super(UserProfileDetailView, self).get_object(queryset)
UserProfile.objects.get_or_create(user=user)
return user
Something like a old way>
def my_view(request, slug):
var = get_object_or_404(Model, slug=slug)
xxx = AnotherModel.objects.filter(var=var)
...
我如何在第一个视图 UserProfileDetailView 中执行此操作,
显示相关数据?
我在这种情况下所做的是将相关对象添加到上下文数据中。它会是这样的:
class UserProfileDetailView(DetailView):
model = get_user_model()
slug_field = "username"
template_name = "perfil.html"
def get_context_data(self, **kwargs):
# xxx will be available in the template as the related objects
context = super(UserProfileDetailView, self).get_context_data(**kwargs)
context['xxx'] = AnotherModel.objects.filter(var=self.get_object())
return context
另一种方法是用 MultipleObjectMixin
扩展 DetailView
,如本例所示:
from django.views.generic import DetailView
from django.views.generic.list import MultipleObjectMixin
from django.contrib.auth import get_user_model
class DetailListView(MultipleObjectMixin, DetailView):
related_model_name = None
def get_queryset(self):
# a bit of safety checks
if not hasattr(self, "related_model_name"):
raise AttributeError(
"%s.related_model_name is missing." % (
self.__class__.__name,))
if not self.related_object_name:
raise NotImplementedError(
"%s.related_model_name must not be None." % (
self.__class__.__name,))
# get the object
obj = self.get_object()
# get the related model attached to the object
related_model = getattr(obj, "%s_set" % self.related_model_name, None)
# safety check if related model doesn't exist
if not related_model:
raise AttributeError(
"%s instance has no attribute \"%s_set\"" % (
obj.__class__.__name__, self.related_model_name)
# return the related model queryset
return related_model.all()
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
return super(DetailListView, self).get(request, *args, **kwargs)
class UserProfileDetailView(DetailListView):
template_name = "perfil.html"
model = get_user_model()
slug_field = "username"
related_model_name = "anothermodel"
def get_object(self, queryset=None):
user = super(UserProfileDetailView, self).get_object(queryset)
UserProfile.objects.get_or_create(user=user)
return user
在我看来,这种方法不太清晰和易于理解,但它在可重用性方面具有巨大优势。它肯定有一个缺点:如果您使用 class 变量 context_object_name
,它将引用相关对象列表而不是对象本身(这与继承链的设置方式有关在构造 class).
时
我想return到用户相关记录。 有人可以帮助我吗?
我的部分观点
class UserProfileDetailView(DetailView):
model = get_user_model()
slug_field = "username"
template_name = "perfil.html"
def get_object(self, queryset=None):
user = super(UserProfileDetailView, self).get_object(queryset)
UserProfile.objects.get_or_create(user=user)
return user
Something like a old way>
def my_view(request, slug):
var = get_object_or_404(Model, slug=slug)
xxx = AnotherModel.objects.filter(var=var)
...
我如何在第一个视图 UserProfileDetailView 中执行此操作, 显示相关数据?
我在这种情况下所做的是将相关对象添加到上下文数据中。它会是这样的:
class UserProfileDetailView(DetailView):
model = get_user_model()
slug_field = "username"
template_name = "perfil.html"
def get_context_data(self, **kwargs):
# xxx will be available in the template as the related objects
context = super(UserProfileDetailView, self).get_context_data(**kwargs)
context['xxx'] = AnotherModel.objects.filter(var=self.get_object())
return context
另一种方法是用 MultipleObjectMixin
扩展 DetailView
,如本例所示:
from django.views.generic import DetailView
from django.views.generic.list import MultipleObjectMixin
from django.contrib.auth import get_user_model
class DetailListView(MultipleObjectMixin, DetailView):
related_model_name = None
def get_queryset(self):
# a bit of safety checks
if not hasattr(self, "related_model_name"):
raise AttributeError(
"%s.related_model_name is missing." % (
self.__class__.__name,))
if not self.related_object_name:
raise NotImplementedError(
"%s.related_model_name must not be None." % (
self.__class__.__name,))
# get the object
obj = self.get_object()
# get the related model attached to the object
related_model = getattr(obj, "%s_set" % self.related_model_name, None)
# safety check if related model doesn't exist
if not related_model:
raise AttributeError(
"%s instance has no attribute \"%s_set\"" % (
obj.__class__.__name__, self.related_model_name)
# return the related model queryset
return related_model.all()
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
return super(DetailListView, self).get(request, *args, **kwargs)
class UserProfileDetailView(DetailListView):
template_name = "perfil.html"
model = get_user_model()
slug_field = "username"
related_model_name = "anothermodel"
def get_object(self, queryset=None):
user = super(UserProfileDetailView, self).get_object(queryset)
UserProfile.objects.get_or_create(user=user)
return user
在我看来,这种方法不太清晰和易于理解,但它在可重用性方面具有巨大优势。它肯定有一个缺点:如果您使用 class 变量 context_object_name
,它将引用相关对象列表而不是对象本身(这与继承链的设置方式有关在构造 class).