2015-12-21 61 views
1

我正在嘗試爲我的視圖創建一些驗證邏輯。爲了不再重複我自己,我希望將驗證邏輯放在一個函數中,然後可以通過其他視圖函數調用它。驗證功能稱爲check_if_account_valid。但是,它看起來像嵌入在驗證功能中的HttpResponseRedirect未被調用 - subscription_status檢查工作(打印出'訂閱狀態已失效'),但重定向不會發生。檢查一個帳戶在Django中是否有效

如何在每個視圖被調用時執行一些驗證邏輯?是否有理由不能從另一個視圖中調用視圖?有沒有更好的方法來做到這一點?

models.py

class Account(models.Model): 

    SUBSCRIPTION_CHOICES = (
     ('Dev Account', 'Dev Account for Testing'), 
     ('15 day trial', '15 day trial'), 
     ('Paid', 'Paid account - payment up to date'), 
     ('Lapsed', 'Paid account - payment lapsed'), 
     ('Inactive', 'Inactive'), 
     ) 

    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    subscription_status = models.CharField(choices=SUBSCRIPTION_CHOICES, default='15 day trial', 
              max_length=100) 
    date_created = models.DateTimeField(auto_now_add=True) 

views.py

def check_if_account_valid(request): 
    if request.user.is_authenticated(): 
     subscription_status = request.user.account.subscription_status 
     date_created = request.user.account.date_created 
     if subscription_status == '15 day trial': 
      localtz = pytz.timezone('Europe/Lisbon') 
      now_datetime = datetime.datetime.utcnow() 
      now_datetime_loc = localtz.localize(now_datetime) 
      # check if trial is up 
      if (date_created - now_datetime_loc) < datetime.timedelta(days=15): 
       pass 
      # if it is up, do nothing 
      else: 
       return HttpResponseRedirect('/subscription/trial_ended/') 
     elif subscription_status == 'Paid': 
      pass 
     elif subscription_status == 'Lapsed': 
      print('Subscription status is lapsed') 
      return HttpResponseRedirect('/subscription/lapsed/') 
     elif subscription_status == 'Inactive': 
      return HttpResponseRedirect('/subscription/inactive/') 
    else: 
     return HttpResponseRedirect('/login/') 

def home(request): 
    check_if_account_valid(request) 
    context = {} 
    return render(request, 'home.html', context) 

Django的== 1.8.4

+0

你爲什麼創建了一個'check_if_account_valid'視圖?您可以將它變成一個簡單的功能! – utkbansal

回答

0

這是因爲你是從check_if_account_valid返回HttpResponseRedirecthome但那麼不要對他們做任何事情。

0

問題是你沒有回覆你的回覆。爲了讓您的工作方式,您可能需要將其改成這樣:

def check_if_account_valid(request, next_view): 
    if request.user.is_authenticated(): 
     subscription_status = request.user.account.subscription_status 
     date_created = request.user.account.date_created 
     if subscription_status == '15 day trial': 
      localtz = pytz.timezone('Europe/Lisbon') 
      now_datetime = datetime.datetime.utcnow() 
      now_datetime_loc = localtz.localize(now_datetime) 
      # check if trial is up 
      if (date_created - now_datetime_loc) < datetime.timedelta(days=15): 
       pass 
      # if it is up, do nothing 
      else: 
       return HttpResponseRedirect('/subscription/trial_ended/') 
     elif subscription_status == 'Paid': 
      pass 
     elif subscription_status == 'Lapsed': 
      print('Subscription status is lapsed') 
      return HttpResponseRedirect('/subscription/lapsed/') 
     elif subscription_status == 'Inactive': 
      return HttpResponseRedirect('/subscription/inactive/') 
    else: 
     return HttpResponseRedirect('/login/') 

    return next_view 

然後打電話給你的看法是這樣的:

def home(request): 
    context = {} 
    next_view = render(request, 'home.html', context) 
    return check_if_account_valid(request, next_view) 

一個更好的(更Django的等)的方法可能是切換到ClassBased View,創建一個Mixin,其中check_if_account_validdispatch方法中調用。

+0

爲CBV創建mixin很好,但它不是唯一的類似Django的方法。另一個選擇是堅持一個基於功能的視圖並創建一個裝飾器。 – Alasdair

0

你的check_if_account_valid函數返回一個HTTPResponse,但你的home視圖不會做任何事情。

對於代碼工作,你就必須返回響應

def home(request): 
    return check_if_account_valid(request) 
    context = {} 
    return render(request, 'home.html', context) 

但會總是回報,你不想爲有效的帳戶。所以你需要添加一個像下面這樣的支票:

def home(request): 
    response = check_if_account_valid(request) 
    if response is not None: 
     return response 
    context = {} 
    return render(request, 'home.html', context) 

這個工程,但不是很整齊。更好的方法是使check_if_account成爲裝飾者。 Django使用這種方法來裝飾器,如login_requireduser_passes_test。然後你的觀點將簡化爲:

@check_if_account_valid 
def home(request): 
相關問題