- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
免责声明:我对 Python 和 Django 比较陌生。
虽然我的问题不是 Django 特有的,但我经常在这种情况下遇到它。有时,我会向网站添加新功能,这些功能假定经过身份验证的用户并访问只有经过身份验证的用户才具有的属性。然后,当我在另一个未登录的浏览器中访问该页面时,我收到“AttributeNotFound”错误,因为该用户实际上是 AnonymousUser。
那又怎样,没什么大不了的。只需检查是否已通过身份验证:
def my_view(request):
if request.user.is_authenticated():
posts = user.post_set.filter(flag=True).all()
else:
posts = None
return render(request, 'template.html', {posts: posts})
然后在模板中:
<h1>Your Posts</h1>
<ul>
{% for post in posts %}
<li>{{ post.name }}</li>
{%else%}
<p>No posts found.</p>
{%endfor%}
</ul>
但是我在我的代码中经常注意到这种模式,我想做一些事情,前提是满足调用链中的某个条件(即属性不是 None),或者只是返回 None、空集或类似的东西。
所以我立即想到了选项(如 Scala 中所示),但由于 python 中 lambda 表达式的繁琐语法,我不太喜欢结果:
# create a user option somewhere in a RequestContext
request.user_option = Some(user) if user.is_authenticated() else Empty()
# access it like this in view
posts = request.user_option.map(lambda u: u.post_set.filter(flag=True).all()).get_or_else(None)
代码被选项语法遮蔽,几乎隐藏了实际意图。此外,我们还必须知道用户必须经过身份验证才能拥有 post_set 属性。
相反,我想要的是一个类似“空合并”的运算符,它允许我编写这样的代码:
def my_view(request):
user_ = Coalesce(user)
posts = user_.post_set.filter(flag=True).all() # -> QuerySet | None-like
return render(request, 'template.html', {posts: posts})
然后我继续编写一个包装类,它实际上允许我执行此操作:
class Coalesce:
def __init__(self, inst):
self.inst = inst
def __call__(self, *args, **kwargs):
return Coalesce(None)
def __iter__(self):
while False:
yield None
def __str__(self):
return ''
def __getattr__(self, name):
if hasattr(self.inst, name):
return getattr(self.inst, name)
else:
return Coalesce(None)
def __len__(self):
return 0
使用 Coalesce 包装用户对象使我能够按照自己的意愿编写代码。如果用户没有定义属性 post_set ,它将表现得像一个空集/列表(关于可迭代)并且计算结果为 False。所以它可以在 Django 模板中工作。
因此,假设合并对象是通过命名约定或显式转换来标记的,这样做可以吗?或者您认为应该避免这样做?如果避免的话,在没有大量 if-else block 的情况下处理可选属性的最佳方法是什么?
最佳答案
您的解决方案是 Null object pattern 的变体。只要明确使用它,我认为使用它就完全没问题。特别是当它提高代码的可读性时。
您还可以使用以下方法扩展您的 Coalesce
类,以允许像这样的索引访问 first_post = user_.post_set.filter(flag=True)[0]
def __getitem__(self, i):
try:
return self.inst[i]
except (TypeError, IndexError, KeyError):
return Coalesce(None)
对于membership tests 在
和不在
:
def __contains__(self, i):
try:
return i in self.inst
except (TypeError, IndexError, KeyError):
return False
关于Python "null coalescing"/级联属性访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22197783/
我正在尝试返回有关所执行搜索次数的每小时报告。我的结果不包括搜索为零的时间,我认为我的语法正确,可以使用 COALESCE。谁能看到我做错了什么?谢谢 SELECT CAST(startdatetim
众所周知,COALESCE 是一个 ANSI SQL 标准函数。它在不同的 RDBMS 中具有相同的功能(即)它返回值列表中的第一个 NOT NULL 值。 考虑以下数据设置 CREATE TABLE
## 问题## 我从这个脚本中收到错误(Postgresql 9.3.2) (在 MS SQL Server 中没问题) SELECT CASE COALESCE(my_date_field,0)
只是想看看是否有人有更好的方法来完成我所需要的。 先来个背景。我的数据库中有一个表,目前大约有 20,000 行。在表中,我们有一列用于 FirstName 和 LastName。还有一列是 Refe
我在 SO 中找不到它,并且认为在这里找到它可能是值得的,因为 oracle 文档没有指定它。 http://docs.oracle.com/cd/B28359_01/server.111/b2828
我刚刚了解了 COALESCE,我想知道是否可以在两个表之间合并整行数据?如果没有,以下散漫的最佳方法是什么? 例如,我有这两个表并假设所有列都匹配: tbl_员工 Id Name E
为什么此查询在某些情况下会产生重复项? Table_1 ID 1 2 3 Table_2 ID 1 2 4 Table_3 ID 1 3 4 询问: SELECT C
我有一张名为 table1 的表带列Gender varchar(10)和 Team numeric . create table table1 ( ID integer Gender varchar
SQL Server 2005 中是否有一个函数,如果任何参数(任何类型)为 NULL,它会返回 NULL [或 bool 值],这样我就不用编写 IF a 为 NULL 或 b 为 NULL 或 c
来自this question , a neat answer about using COALESCE简化复杂的逻辑树。我考虑了短路的问题。 例如,在大多数语言的函数中,参数都会被完全求值,然后传递
// lItems is TDataSet or TClientDataSet with lItems do begin Close; Filtered := false; Fi
我有一个包含季度值的表,我需要添加一个新列,为我提供上个季度的最后一个非空值。例如 ID | Project | Q1 | Q2 | Q3 | Q4 | Current Quarte
大家好,Stackoverflowers!我有一个正在处理的查询,我需要过滤掉 0,但它没有删除那些记录,我似乎无法弄清楚原因。 请看下面, SELECT disb_sum, pl_balance,
我是 mysql 触发器的新手。只是让我的头脑思考一些事情,以便我了解某些内容是否可能未正确编码或最有效的路线:) 我想做的是在添加数据库条目后通过提交的值连接表以创建用于全文搜索的文本字符串,因为我
我是 REDSHIFT 中 COALESCE 功能的新手。我在 mysql 和 Redshift 中运行了以下四个查询。 第一个和第二个查询在 mysql 和 redshift 中均按预期执行。但对于
首先,我想澄清一下,我已经阅读过 this问题。那里描述的问题与我的问题非常相似,但与一个错误有关,该错误已经解决。 通过在 Windows 上运行的 MySQL WorkBench 5.2.47 C
我有这两张表: users(这有一个 updated_at 列)和 user_updates(这有一个用户的外键 user_id 和一个 created_at 列) 我想为用户找到最新的用户更新,所以
我正在使用 Postgres 并有以下 SQL 语句: SELECT * FROM "osmlocal-dsd-de".t_osm_vehicle_image t WHERE t.vehicle_co
如果我有一个简单的查询 SELECT row FROM table WHERE id=my_id 如果找不到 my_id,我想要一行 NULL 而不是空行,我可以使用 coalesce COALESC
我有一个使用 COALESCE(timestamp_type::date,charachter_varying) 的查询,由于数据类型不匹配而失败: 错误:无法匹配 COALESCE 类型的日期和字符
我是一名优秀的程序员,十分优秀!