
[英]How do I set a specific value for an attribute of a model every time I save it on Django?
[英]Have attribute set to specific value on every query
我使用psycopg2访问我在 SQL 中构建的 (PostgreSQL) 数据库。我希望有不同的用户,它们只能访问表中自己的行。 因此,我向方案中的每个表添加了一个UserId
属性。 UserId 的值可作为变量(让我们将其命名为pyUserId
)提供给执行的程序。 我通过我定义的一个 function 对curs.execute()
go 的所有调用。
我是否可以为每个查询集中设置一个属性的值,比如UserId=pyUserId
? 否则我必须将 pyUserId 作为我已经构建的每个查询的数据传递,我怀疑这也违反了 DRY。
例如:
SELECT UserName FROM Users WHERE Age < 30
变为:
SELECT UserName FROM Users WHERE Age < 30 AND UserId = pyUserId
或者
INSERT INTO Profiles (Name, Bio, SoAccount) VALUES ('jon', 'blah...', '22656')
变成INSERT INTO Profiles (Name, Bio, SoAccount, UserId) VALUES ('jon', 'blah...', '22656', pyUserId)
DELETE
等相同。
Snakecharmer 的评论帮助我实现了以下内容。
在特定行属于特定用户的所有表中都有一个属性UserId
:
CREATE TABLE Users (
UserId INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_attributes ...
CREATE TABLE some_table (
UserId INTEGER REFERENCES Users(UserId)
DEFAULT current_setting('my_app.CurrentUserId')::INTEGER NOT NULL,
some_attribute INTEGER, ...
基于本教程:定义一个 session 变量,当用户通过身份验证并在上面用作DEFAULT
时设置该变量:
SQL = "SET my_app.CurrentUserId = %s"
data = (self.__userId, )
cur.execute(SQL, data)
实施Row-Level Security ,以创建仅允许访问UserId
等于 session 变量的策略:
DO -- Create a loop over all tables to create a policy and enable it for them
$$
DECLARE
row record;
BEGIN
FOR row IN SELECT tablename FROM pg_tables AS t
WHERE t.schemaname = 'public'
AND NOT t.tablename ~* 'exclude|tables|regex'
LOOP
EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY;', row.tablename);
EXECUTE format('CREATE POLICY isolateUserId ON %I TO some_user
USING (UserId = current_setting(''my_app.CurrentUserId'')::INTEGER);', row.tablename); -- Escape ' !
END LOOP;
END;
$$;
some_user
是您在 psycopg2 中用来连接数据库的用户。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.