Django - 常见数据,几个视图

时间:2017-06-19 14:28:22

标签: django

我需要你的帮助,因为我有大约6个有共同数据的观点。

与我的问题类似的例子:

def informationPlayers(request,nameTeam):

    try :
        team = Team.objects.get(name = nameTeam)    
    except Team.DoesNotExist:
        return redirect(teams)


    if not request.user.is_authenticated():         
        formLogin   = loginForm(auto_id=False)
        countMembers = team.members.count()
    else :      
        members    = team.members.members()

    ... code specific to this view ...


def informationCoach(request,nameTeam):

    try :
        team = Team.objects.get(name = nameTeam)    
    except Team.DoesNotExist:
        return redirect(teams)


    if not request.user.is_authenticated():         
        formLogin   = loginForm(auto_id=False)
        countMembers = team.members.count()
    else :      
        members    = team.members.members()

    ... code specific to this view ...

所以这两个视图具有相同的变量和算法(如果用户是否经过身份验证)。

我不想在使用它们的所有视图中写这个algortihm和变量,我该怎么办?

我已经尝试过TEMPLATE_CONTEXT_PROCESSORS,但它已应用于我网站的所有视图/页面,我不希望这样。

2 个答案:

答案 0 :(得分:0)

以下是使用类基本视图的答案。 Python中的类(以及支持它们的任何其他语言)是共享代码的好方法,同时使任何其他开发人员明白应该和不应该共享此代码。

除了您需要调用类方法之外,您的urls.py应保持相同。类似的东西:

from django.conf.urls import *
from .views import *

urlpatterns = [
    url(r'^(?P<nameTeam>[^/]+)/player/$', PlayerView.as_view(), name='player_view'),
    url(r'^(?P<nameTeam>[^/]+)/coach/$', CoachView.as_view(), name='player_view'),
]

然后在views.py上,你会做类似的事情:

class TeamAccessMixin(object):
    # This is really just a regular Python object
    team = None
    formLogin = None
    countMembers = None
    members = None

    def get_team(self, teamName):
      try :
        self.team = Team.objects.get(name = nameTeam)    
      except Team.DoesNotExist:
        return redirect(self.teams)

      if not self.request.user.is_authenticated():         
        self.formLogin = loginForm(auto_id=False)
        self.countMembers = team.members.count()
      else :      
        self.members = team.members.members()

class PlayerView(TeamAccessMixin, DetailView):
    model = Player
    template_name = 'team/player.html'

    def get_context_data(self, **kwargs):
        context = super(PlayerView, self).get_context_data(**kwargs)
        self.get_team(kwargs['teamName']);
        context['team'] = self.team
        context['members'] = self.members
        # Special code to add additional context specific to this view
        ...
        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(PlayerView, self).dispatch(request, *args, **kwargs)

class CoachView(TeamAccessMixin, DetailView):
    model = Coach
    template_name = 'team/coach.html'

    def get_context_data(self, **kwargs):
        context = super(CoachView, self).get_context_data(**kwargs)
        self.get_team(kwargs['teamName']);
        context['team'] = self.team
        context['members'] = self.members
        # Special code to add additional context specific to this view
        ...
        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(CoachView, self).dispatch(request, *args, **kwargs)

回答您的具体问题,但我也看到您可能无法理解Django的其他方面(例如登录装饰器,它将确保用户登录或自动重定向)。所以,作为一个额外的奖励,这里是我将如何实现你想要做的事情(假设你没有指定一些细节):

class TeamAccessMixin(object):
    # This is really just a regular Python object

    def get_object(self, queryset=None):
      # It is best practice to simply give a 404 if the record does not exist
      object = get_object_or_404(Team, slug=self.kwargs['nameTeam'])
      return object

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        # the decorator will ensure all users are logged in or will redirect to login page
        return super(TeamAccessMixin, self).dispatch(request, *args, **kwargs)

class PlayerView(TeamAccessMixin, DetailView):
    model = Player
    template_name = 'team/player.html'

    def get_context_data(self, **kwargs):
        context = super(PlayerView, self).get_context_data(**kwargs)
        context['team'] = self.object
        context['members'] = self.object.members
        # Special code to add additional context specific to this view
        ...
        return context

class CoachView(TeamAccessMixin, DetailView):
    model = Player
    template_name = 'team/coach.html'

    def get_context_data(self, **kwargs):
        context = super(CoachView, self).get_context_data(**kwargs)
        context['team'] = self.object
        context['members'] = self.object.members
        # Special code to add additional context specific to this view
        ...
        return context

答案 1 :(得分:0)

谢谢@dkarchmer,我做了类似的事情:

版本已修改:

class ProjetMixin(object) :

    project = None
    coms = None
    form = None

    def get_context_data(self, *args, **kwargs) :

        context = super(ProjetMixin, self).get_context_data(*args, **kwargs)

        try :
            self.project = Project.objects.get(name = self.kwargs['name']) #in urls 

        except Project.DoesNotExist:
            return redirect(projects)

        self.coms = self.project.coms_set.order_by('-date_send')

        if not self.request.user.is_authenticated():        
            self.form = formForm(auto_id=False)         

        context['project'] = self.project
        context['coms'] = self.coms
        context['form'] = self.form

        return context


class FicheProjetView(ProjetMixin, TemplateView):
    template_name = 'path/homeProject.html'

    def get_context_data(self, **kwargs):

        context = super(FicheProjetView, self).get_context_data(**kwargs)

        if self.request.POST :
            ...                                 

    return context

    def dispatch(self, request, *args, **kwargs):
        return super(FicheProjetView, self).dispatch(request, *args, **kwargs)

这是对的?