django 在 forms.ModelForm 里怎么获得当前的登录用户?

98 天前
 python30

django 在 forms.ModelForm 里怎么获得当前的登录用户? 想在 forms.ModelForm 里用当前登录用户与信息作者用户做个比较。不知道有什么办法可以在 forms.ModelForm 这里面取得当前的登录用户。 谢谢各位

views.py 里:

#用户编辑贴子
class Edit_Topic(UpdateView):
	model = Topic
	slug_field = 'pk'
	slug_url_kwarg = 'pk'
	form_class = EditTopicForm
	template_name = 'gqinfo/edit_topic.html'
	context_object_name = 'topic'
	def get_success_url(self):
		t = Topic.objects.get(id=self.kwargs.get('pk'))
		if t.hidden:#信息未审核,跳转到待审列表
			return reverse("info:shenhe_list")
		else:#信息审核后直接显示
			return reverse_lazy("info:topic_detail", kwargs={'pk':t.id})

forms.py

class EditTopicForm(forms.ModelForm):
	def __init__(self, *args, **kwargs):
		self.instance = kwargs.get('instance', None)
		self.request = kwargs.get('request', None)#这里取不到数据
		super(EditTopicForm, self).__init__(*args, **kwargs)



	class Meta:
		model = Topic
		#fields = "__all__"
		fields = ['title', 'infocategory', 'category', 'body', 'tags', 'ys_t']
		
	# def form_valid(self, form):
		# form.instance.created_by = self.request.user
		# return super().form_valid(form)
		
	def save(self):
		inst = super(EditTopicForm, self).save()
		print (self.request) #这里没有这个 request
		print (inst.author.is_superuser, 'dddddd') #这里显示的是信息发布者的用户。不是当前登录的用户
		return inst
		

在 forms.ModelForm 里怎么获得当前的登录用户? 想在 forms.ModelForm 里用当前登录用户与信息作者用户做个比较。不知道有什么办法可以在 forms.ModelForm 这里面取得当前的登录用户。 谢谢各位

1449 次点击
所在节点    Python
19 条回复
echoless
98 天前
python30
98 天前
@echoless 不太明白,这跟上面的问题的关系。。。
coolair
98 天前
init 中获取不到,除非你在 view 里面显示的传。

可以在 form_valid 中使用 self.request.user 获取,只需重写这个函数就可以了。
python30
98 天前
@coolair 能详细一点吗。一点思路也没有。谢谢
sduoduo233
98 天前
重写 get_form_kwargs ,把 requeest.user 加进去,然后就可以在 EditTopicForm 的__init__拿到了
(我没试过)
mylifcc
98 天前
self.request.user 不就行了
python30
98 天前
@mylifcc 这个取不到值。这里的 self 里面没有 request
coolair
98 天前
class EditTopicForm(forms.ModelForm):
def form_valid(self, form):
print(self.request.user)
return super().form_valid(form)
lybcyd
98 天前
可以说一下目的吗?需要当前用户信息做什么样的事情
python30
98 天前
@coolair 这样写出来,怎么在后面的 save() 里面用? 怎么调用或在 save 里面用 request?
python30
98 天前
@lybcyd 目的是这样的,
用户发布信息后,修改信息会扣除发布者的积分。
如果是管理员给用户修改信息。则不会扣除用户的积分
这里的 inst.author 是发布者
所以想取得当前登录用户 admin ,做个判断
是 admin 修改信息就不扣除或扣 admin 的积分。而不是扣用户发布者的积分
lybcyd
98 天前
@python30 这个功能应该写在 view 里,form 的 save 应该只负责表单内的 Topic 数据的保存。前面提到的 form_valid 也不是 form 的方法,而是 CreateView/UpdateView 的方法。在 View 里重写 form_valid 方法,先执行父类的 form_valid 保存数据,然后拿到用户并视情况与否更新积分,最后重定向。别忘了加上事务。
python30
98 天前
@lybcyd 已经解决了。谢谢
综合上面的朋友们的建议,主要是 @sduoduo233

views.py
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs()
kwargs.update({'request':self.request})
return kwargs

然后在 forms.ModelForm 的__init__里面用这个取:
self.request = kwargs.pop('request', None)

就可以在后面的 save 里面用了
感谢各位
lybcyd
98 天前
https://gist.github.com/lybcyd/5663a7bc15303dbda9cf5dafa5de63c4
大义如上,根据你的实际代码更改一下
pililink
98 天前
request.user
zonde306
98 天前
可以自己写一个 middleware 捕获 request 放到 全局/模块/单例
例如我自己写的 middleware:
```python
import contextvars
import django.http

GLOBAL_REQUEST = contextvars.ContextVar("GLOBAL_REQUEST", default=None)

class GlobalRequest:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
global GLOBAL_REQUEST
GLOBAL_REQUEST.set(request)
return self.get_response(request)

# 用这个获取 request 实例
def get_request() -> django.http.HttpRequest:
return GLOBAL_REQUEST.get()

```
zonde306
98 天前
HashV2
98 天前
打个断点看看上下文,valid 相关的钩子函数应该可以拿到,如果拿不到建议这块逻辑挪到 serializer 里
volvo007
96 天前
@python30 你修改信息必然用 post (或者什么别的)方法发起请求。那服务器一定可以拿到这次请求的参数,由于修改数据一般是注册用户才能做的,所以参数里面必然会有 user 信息。 这部分就是通过 self.request.user 拿到的。你的 view 函数里应该有个 request 参数呀,是个 django 的 HttpRequest 的实例

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1064097

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX