V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
python30
V2EX  ›  Python

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

  •  
  •   python30 · 98 天前 · 1449 次点击
    这是一个创建于 98 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 这里面取得当前的登录用户。 谢谢各位

    19 条回复    2024-08-13 12:29:17 +08:00
    python30
        2
    python30  
    OP
       98 天前
    @echoless 不太明白,这跟上面的问题的关系。。。
    coolair
        3
    coolair  
       98 天前
    init 中获取不到,除非你在 view 里面显示的传。

    可以在 form_valid 中使用 self.request.user 获取,只需重写这个函数就可以了。
    python30
        4
    python30  
    OP
       98 天前
    @coolair 能详细一点吗。一点思路也没有。谢谢
    sduoduo233
        5
    sduoduo233  
       98 天前 via Android
    重写 get_form_kwargs ,把 requeest.user 加进去,然后就可以在 EditTopicForm 的__init__拿到了
    (我没试过)
    mylifcc
        6
    mylifcc  
       98 天前
    self.request.user 不就行了
    python30
        7
    python30  
    OP
       98 天前
    @mylifcc 这个取不到值。这里的 self 里面没有 request
    coolair
        8
    coolair  
       98 天前
    class EditTopicForm(forms.ModelForm):
    def form_valid(self, form):
    print(self.request.user)
    return super().form_valid(form)
    lybcyd
        9
    lybcyd  
       98 天前
    可以说一下目的吗?需要当前用户信息做什么样的事情
    python30
        10
    python30  
    OP
       98 天前
    @coolair 这样写出来,怎么在后面的 save() 里面用? 怎么调用或在 save 里面用 request?
    python30
        11
    python30  
    OP
       98 天前
    @lybcyd 目的是这样的,
    用户发布信息后,修改信息会扣除发布者的积分。
    如果是管理员给用户修改信息。则不会扣除用户的积分
    这里的 inst.author 是发布者
    所以想取得当前登录用户 admin ,做个判断
    是 admin 修改信息就不扣除或扣 admin 的积分。而不是扣用户发布者的积分
    lybcyd
        12
    lybcyd  
       98 天前
    @python30 这个功能应该写在 view 里,form 的 save 应该只负责表单内的 Topic 数据的保存。前面提到的 form_valid 也不是 form 的方法,而是 CreateView/UpdateView 的方法。在 View 里重写 form_valid 方法,先执行父类的 form_valid 保存数据,然后拿到用户并视情况与否更新积分,最后重定向。别忘了加上事务。
    python30
        13
    python30  
    OP
       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
        14
    lybcyd  
       98 天前
    https://gist.github.com/lybcyd/5663a7bc15303dbda9cf5dafa5de63c4
    大义如上,根据你的实际代码更改一下
    pililink
        15
    pililink  
       98 天前
    request.user
    zonde306
        16
    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
        17
    zonde306  
       98 天前
    HashV2
        18
    HashV2  
       97 天前
    打个断点看看上下文,valid 相关的钩子函数应该可以拿到,如果拿不到建议这块逻辑挪到 serializer 里
    volvo007
        19
    volvo007  
       96 天前 via iPhone
    @python30 你修改信息必然用 post (或者什么别的)方法发起请求。那服务器一定可以拿到这次请求的参数,由于修改数据一般是注册用户才能做的,所以参数里面必然会有 user 信息。 这部分就是通过 self.request.user 拿到的。你的 view 函数里应该有个 request 参数呀,是个 django 的 HttpRequest 的实例
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3447 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:51 · PVG 08:51 · LAX 16:51 · JFK 19:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.