【问题标题】:Set first_name, last_name and email from User model as default value in field将用户模型中的 first_name、last_name 和 email 设置为字段中的默认值
【发布时间】:2018-09-30 21:02:53
【问题描述】:

我正在尝试在我的模型中为 first_namelastnameemail 设置默认值

得到以下型号

from django.db import models
from django.contrib.auth.models import User

class Project(models.Model):
        firstname = models.CharField(max_length=30, blank=True, verbose_name=_("label_general_firstname"), default=User.first_name)
        lastname = models.CharField(max_length=30, blank=True, verbose_name=_("label_general_lastname"), default=User.last_name)
        email = models.EmailField(blank=True, verbose_name=_("label_general_email"), default=User.email)

运行迁移时,我收到以下错误:

ValueError: Cannot serialize: <django.db.models.query_utils.DeferredAttribute object at 0x7f459e8aac50>

我让用户通过 SSO 进入,他们已经填写了某些字段。 在使用使用此模型的表单时,我想将它们用作默认值。

尝试了几种方法,但都没有得到有效的结果。

编辑:

这是我从这个应用程序中理解工作流程的方式:

projects/urls.py 我看到以下内容

url(r'^(?P<pk>[0-9]+)$',
        login_required(PermCheckUpdateView.as_view(
            model = Project,
            form_class = ProjectGeneralForm,
            template_name = "project/general.html",
            success_url = "/projects/{id}")),
        name = "project_update_general"),

所以PermCheckUpdateView 视图似乎正在呈现表单

app/views.py我可以看到这样的视图:

class PermCheckUpdateView(ObjectPermCheckMixin,CallableSuccessUrlMixin,UpdateView):
    # make the form readonly if its only readable
    def get_form(self):
        form = super(PermCheckUpdateView, self).get_form()

        if not self.object.has_write_permission(self.request.user) and not self.request.user.is_staff:
            for field in form.fields.values():
                field.widget.attrs["readonly"] = "readonly"
            if hasattr(form,"helper"):
                form.helper.inputs = []
        return form

回去吧,这里是ObjectPermCheckMixin

class ObjectPermCheckMixin(ObjectPermCheckGETMixin, ObjectPermCheckPOSTMixin):
    pass

还有ObjectPermCheckGETMixinObjectPermCheckPOSTMixin

class ObjectPermCheckGETMixin(object):
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        if not self.object.has_read_permission(self.request.user) and not request.user.is_staff:
            raise PermissionDenied
        return super(ObjectPermCheckGETMixin, self).get(request, *args, **kwargs)

class ObjectPermCheckPOSTMixin(object):
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        if not self.object.has_write_permission(self.request.user) and not request.user.is_staff:
            raise PermissionDenied
        return super(ObjectPermCheckPOSTMixin, self).post(request, *args, **kwargs)

我尝试在他们两个中设置 request.user,但到目前为止都失败了。 其中一个错误是 __init__ 需要 2 个输入,但只给出了一个。

我不太了解 Django,无法自己解决这个问题。 非常感谢任何帮助。

【问题讨论】:

  • 你不能这样做,在这个模型中,甚至没有(相关的)User。这是表单、视图等应该执行的操作。
  • 也尝试访问表单中的用户对象,但出现了不同的问题stackoverflow.com/questions/52545946/…

标签: django django-models


【解决方案1】:

defaults 要么是一个真实值,要么是一个可调用的(不带参数)在运行时生成一个值(例如取决于设置、数据库查询、时间戳等)

如果一个字段的默认值依赖于其他字段,您可以覆盖.save(..) 函数,但即使这样也不可取,因为可以绕过.save(..) 函数(在批量插入等情况下) )。

由于这里User没有存储在项目中,所以应该在Form或视图中处理。例如:

class MyForm(Form):

    def __init__(*args, user=None, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        if user and self.instance.pk is None:  # new item constructed
            self.instance.firstname = user.first_name
            self.instance.lastname = user.last_name

如果你在视图中构造这样的表单,你需要传递request.user作为命名参数:

def some_view(request):
    form = MyForm(user=request.user)
    # ...

但是请注意,如果firstnamelastname 依赖于User,则最好将ForeignKey 添加到User。否则你会引入数据重复

【讨论】:

  • 我多次发现这种方法。问题在于,在这种情况下,没有生成表单的视图。表单正在从单个模板变量呈现。
  • @derchris:但是模板不构造表单,它们只渲染它,这意味着视图,隐式或显式地构造了表单。
  • 好的,我想我找到了视图。但是表单构造看起来非常不同。我正在尝试在一个工​​作项目中实现它,而不是我的代码。
  • @derchris:您可以编辑您的问题并分享(相关部分)视图吗?
猜你喜欢
  • 1970-01-01
  • 2020-12-06
  • 2017-10-12
  • 2016-01-16
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多