在字段

时间:2018-09-30 21:02:54

标签: django django-models

我正在尝试为模型中的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,无法自行解决。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

default是真实值,或者是可调用的(不带参数),可在运行时生成值(例如,取决于设置,数据库查询,时间戳等)

如果某个字段的默认值取决于其他字段,则可以覆盖.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。否则,您将引入数据重复