2014-10-10 24 views
0

我正在創建一個Django應用程序,用戶可以在其中創建帳戶,然後向每個帳戶添加事務。它是一個網站的一部分,可以讓用戶跟蹤投資收益。我正在使用泛型類視圖來實現這一點。限制對Django通用視圖的訪問

用戶將交易添加到特定賬戶(代碼未顯示),然後他們必須能夠使用site/transactions/2 /查看該特定賬戶的交易,其中2是賬戶ID。

問題是任何登錄的用戶都可以更改網址以獲取其他用戶帳戶的交易。我可以通過檢查給定的帳戶ID屬於用戶來輕鬆解決此問題,但我認爲必須有更好的方法。有沒有更好的方法可以實現這個目標?我應該不是URL編碼這個?無論如何,我並不喜歡用戶在數據庫中看到他們的帳戶ID的想法。

另外,在稍後的階段,我想讓用戶可以在單個列表中查看其帳戶的一些交易。例如,顯示其5個帳戶中的3個的所有交易。那麼這個URL方法也不會真的起作用。我還有什麼其他選擇?

在models.py我:

class Account(models.Model): 
    name = models.CharField(max_length=40, unique=True, db_index=True) 
    user = models.ForeignKey(User) 

class Transaction(models.Model): 
    value = models.DecimalField(max_digits=15, decimal_places=2) 
    date = models.DateField('transaction date') 
    account = models.ForeignKey(Account) 

在urls.py:

url(r'^(?P<account_id>\d+)/$', views.IndexView.as_view(), name='index'), 

在views.py:

class IndexView(LoginRequiredMixin, generic.ListView): 
    model = Transaction 

    def get_queryset(self): 
     account_id = self.kwargs['account_id'] 
     queryset = Transaction.objects.filter(account_id=account_id) 
     return queryset 

然後,我有一個transaction_list模板

謝謝

回答

1

如果您想要發生404錯誤,您可以使用幫助函數get_object_or_404()首先獲取帳戶對象。

像這樣:

def get_queryset(self): 
    account_id = self.kwargs['account_id'] 

    # raise 404 if no account is found for the current user 
    account = get_object_or_404(Account, pk=account_id, user=self.request.user) 

    queryset = Transaction.objects.filter(account=account) 
    return queryset 

對於你提到,你既可以使一個新的觀點,或者只是檢查是否'account_id'是在URL中,並重新使用當前視圖的第二件事。無論哪種方式,您都需要一個新的網址。

urls.py:

url(r'^(?P<account_id>\d+)/$', views.IndexView.as_view(), name='index'), 
url(r'^$', views.IndexView.as_view(), name='index'), 

再次修改你的get_queryset()的情況下沒有帳戶ID是在URL:

def get_queryset(self): 
    # account_id will be None if the second url was the one that matched. 
    account_id = self.kwargs.get('account_id', None) 

    if account_id: 
     # raise 404 if no account is found for the current user 
     account = get_object_or_404(Account, pk=account_id, user=self.request.user) 

     queryset = Transaction.objects.filter(account=account) 
    else: 
     # we're going to show all transactions for the user, rather than a specific account 
     queryset = Transaction.objects.filter(account__user=self.request.user) 

    return queryset 
+0

非常感謝!我認爲應該這樣做。我對django相當陌生,所以我想知道,像這個例子一樣,在URL中使用數據庫字段ID是否是一種好的做法? – Johan 2014-10-10 16:16:17

+0

它非常標準,是的。一個更好,更友好的方式可能是使用slu instead代替。但我認爲它不好的做法是使用id。 – jproffitt 2014-10-10 16:17:53