Django 过滤和查询:在 views.py、模板或过滤器中进行?
Django filtering and querying: do it in views.py, template, or filters?
所以我正在做一个小的 Django 项目,目前不需要优化。但是为了将来做准备,我想多了解一下这三种方法。
例如,作为模型的一部分,我有 User
和 UserProfile
、Transaction
。
class User(models.Model):
name = ...
email = ...
class UserProfile(models.Model):
user = models.ForeignKey(User, related_name='profile')
photo = models.URLField(...)
...
class Transaction(models.Model):
giver = models.ForeignKey(User, related_name="transactions_as_giver")
receiver = models.ForeignKey(User, related_name='transactions_as_receiver')
...
我经常需要做类似 "return transactions
that the request.user
is giver
or receiver
" 或 "return the profile photo of a user" 的事情。我有几种选择,例如要获得待处理交易列表和双方的 photo
s,我可以在 views.py
级别进行:
1.
#views.py
transactions = Transaction.objects.filter(Q(giver=request.user)|Q(receiver=request.user))
for transaction in transactions:
giver_photo = transactions.giver.profile.all()[0].photo
# or first query UserProfile by
# giver_profile = UserProfile.objects.get(user=transaction.giver),
# then giver_photo = giver_profile.photo
#
# Then same thing for receiver_photo
transaction['giver_photo'] = giver_photo
...
或者我可以在template
水平上做更多:
# some template
<!-- First receive transactions from views.py without photo data -->
{% for t in transactions %}
{{t.giver.profile.all.0.photo}}, ...
{% endfor %}
或者我可以将上面的部分甚至全部内容移动到 filters.py
# some template
{{ for t in request.user|pending_transactions }}
{{ t.giver|photo }} {{ t.receiver|photo }}
{{ endfor }}
其中 photo
和 pending_transactions
与原始 views.py
中的代码大致相同,但已移至过滤器。
所以我想知道是否有关于如何选择哪种方法的最佳 practice/guide 行?
根据 Django 文档,较低级别更快,因此 2. 3. 应该比 1 慢;但是比较 2. 和 3. 怎么样?
在获取用户照片时,应推荐两者中的哪一个,transactions.giver.profile.all()[0].photo
OR profile = UserProfile.objects.get(...) --> photo = profile.photo
?
将此逻辑移至模型和管理器中。视图和模板必须尽可能短。
class User(models.Model):
...
def transactions(self):
return Transaction.objects.filter(Q(giver=self)|Q(receiver=self))
def photo(self):
return self.profile.all().first().photo
因此模板将是:
{% for t in request.user.transactions %}
{{ t.giver.photo }} {{ t.receiver.photo }}
{% endfor %}
我的经验表明,模型中的业务逻辑比 views/templates 中的业务逻辑更容易测试、支持和重用。
所以我正在做一个小的 Django 项目,目前不需要优化。但是为了将来做准备,我想多了解一下这三种方法。
例如,作为模型的一部分,我有 User
和 UserProfile
、Transaction
。
class User(models.Model):
name = ...
email = ...
class UserProfile(models.Model):
user = models.ForeignKey(User, related_name='profile')
photo = models.URLField(...)
...
class Transaction(models.Model):
giver = models.ForeignKey(User, related_name="transactions_as_giver")
receiver = models.ForeignKey(User, related_name='transactions_as_receiver')
...
我经常需要做类似 "return transactions
that the request.user
is giver
or receiver
" 或 "return the profile photo of a user" 的事情。我有几种选择,例如要获得待处理交易列表和双方的 photo
s,我可以在 views.py
级别进行:
1.
#views.py
transactions = Transaction.objects.filter(Q(giver=request.user)|Q(receiver=request.user))
for transaction in transactions:
giver_photo = transactions.giver.profile.all()[0].photo
# or first query UserProfile by
# giver_profile = UserProfile.objects.get(user=transaction.giver),
# then giver_photo = giver_profile.photo
#
# Then same thing for receiver_photo
transaction['giver_photo'] = giver_photo
...
或者我可以在
template
水平上做更多:# some template <!-- First receive transactions from views.py without photo data --> {% for t in transactions %} {{t.giver.profile.all.0.photo}}, ... {% endfor %}
或者我可以将上面的部分甚至全部内容移动到
filters.py
# some template {{ for t in request.user|pending_transactions }} {{ t.giver|photo }} {{ t.receiver|photo }} {{ endfor }}
其中 photo
和 pending_transactions
与原始 views.py
中的代码大致相同,但已移至过滤器。
所以我想知道是否有关于如何选择哪种方法的最佳 practice/guide 行?
根据 Django 文档,较低级别更快,因此 2. 3. 应该比 1 慢;但是比较 2. 和 3. 怎么样?
在获取用户照片时,应推荐两者中的哪一个,transactions.giver.profile.all()[0].photo
OR profile = UserProfile.objects.get(...) --> photo = profile.photo
?
将此逻辑移至模型和管理器中。视图和模板必须尽可能短。
class User(models.Model):
...
def transactions(self):
return Transaction.objects.filter(Q(giver=self)|Q(receiver=self))
def photo(self):
return self.profile.all().first().photo
因此模板将是:
{% for t in request.user.transactions %}
{{ t.giver.photo }} {{ t.receiver.photo }}
{% endfor %}
我的经验表明,模型中的业务逻辑比 views/templates 中的业务逻辑更容易测试、支持和重用。