django admin fieldsets - 添加相关模型的字段

标签 django django-forms django-admin django-models

我有一个模型 EmployeeUser 建立一对一关系.我试图在员工管理中包含一些用户字段 ( first_name, last_name, username, email ),以便直接从员工添加/更改表单编辑这些字段,但我仍然没有想出如何去做。

我看到另一次以类似的方式做这种事情,但现在我有一个字段集错误:
Unknown field(s) (first_name) specified for Employee. Check fields/fieldsets/exclude attributes of class EmployeeAdmin
这是代码:

# FIELDSETS
default_employee_fieldset = (
    ('General', {
        'fields': (
                ('user', 'full_name',),
            ),
        }),
    # ..OTHER FIELDS NOT INCLUDED
    )

finance_fields_employee_fieldset = [
    ('General', {
        'fields': (
                ('full_name',),
                ('first_name', 'last_name')
        ),
        }),
    # ..OTHER FIELDS NOT INCLUDED
    ]



# ADMIN FORM
class EmployeeAdminForm(forms.ModelForm):
    class Meta:
        model = Employee

    def __init__(self, *args, **kwargs):
        super(EmployeeAdminForm, self).__init__(*args, **kwargs)
        self.fields['first_name'] = forms.CharField(_('first name'), max_length=30, blank=True)
        self.fields['last_name'] = forms.CharField(_('last name'), max_length=30, blank=True)

        if 'instance' in kwargs:
            user = kwargs['instance'].user
            self.fields['first_name'].initial = user.first_name
            self.fields['last_name'].initial = user.last_name



# MODEL ADMIN
class EmployeeAdmin(ExtendedAdmin):
    list_display = ('user', 'department', 'line_manager', 'acting_line_manager', 'jobtitle', 'office', 'payroll_id',)
    search_fields = ('user__username', 'user__first_name', 'user__last_name',
                     'line_manager__user__first_name', 'line_manager__user__last_name')
    list_filter = ('department', 'grade', 'clearance', 'office', 'user__is_active', 'user__is_staff',
                   'ready_for_paid_work')
    fieldsets = default_employee_fieldset

    def changelist_view(self, request, extra_context=None):
        extra_context = {'title': 'Employee details'}
        return super(EmployeeAdmin, self).changelist_view(request, extra_context)

    def change_view(self, request, object_id, form_url='', extra_context=None):
        if object_id:
            try:
                record = Employee.objects.get(id=object_id)
                extra_context = {'title': 'Edit employee record: %s' % (str(record),)}
            except (ValueError, Employee.DoesNotExist):
                pass
        # Generate a new CSRF token as this page contains sensitive data
        rotate_token(request)
        return super(EmployeeAdmin, self).change_view(request, object_id, form_url, extra_context)

    def queryset(self, request):
        qs = super(EmployeeAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs
        elif request.user.has_perm('myapp.change_all_employees'):
            if request.user.has_perm('myapp.change_ex_employees'):
                return qs.filter(user__is_staff=True)
            else:
                return qs.filter(user__is_staff=True, user__is_active=True)
        else:
            return qs.filter(user__is_staff=True, user__is_active=True).filter(
                Q(line_manager=request.user.employee) |
                Q(acting_line_manager=request.user.employee) |
                Q(user=request.user)
            )

    def get_form(self, request, obj=None, *args, **kwargs):
        self.form = EmployeeAdminForm
        if obj:
            if request.user.has_perm('myapp.change_hr_employee_data'):
                self.readonly_fields = ('user', )
                self.exclude = None
                self.fieldsets = finance_fields_employee_fieldset
            elif request.user.has_perm('myapp.change_employee_data_operations'):
                if request.user == obj.user:
                    # set readonly fields
                    self.exclude = None
                    self.fieldsets = finance_fields_employee_fieldset
                else:
                     # set readonly fields
                    self.exclude = ('employer_pension_contribution', 'employee_pension_contribution',)
                    self.fieldsets = default_employee_fieldset
            else:
                # if user is in AAA department and not employee's linemanager and not own record
                if request.user.employee.department == settings.DPTS['AAA']
                    if request.user == obj.user:
                        # set readonly fields
                    else:
                        # set readonly fields
                        self.exclude = ('account_number', 'sort_code', 'salary',
                                        'employer_pension_contribution', 'employee_pension_contribution',)
                        self.fieldsets = default_employee_fieldset
                else:
                    # if user is editing his own record
                    if request.user == obj.user:
                        # set readonly fields
                        self.exclude = ('account_reference', 'payroll_id',)
                        self.fieldsets = finance_fields_employee_fieldset[0:-2]
                    # if user is editing some for whom is line manager
                    else:
                        if request.user.employee == obj.line_manager or \
                                        request.user.employee == obj.acting_line_manager:
                            # set readonly fields
                            self.fieldsets = default_employee_fieldset
                            self.exclude = ('employer_pension_contribution', 'employee_pension_contribution',)
        else:
            self.readonly_fields = ()
            self.exclude = ()
            self.fieldsets = default_employee_fieldset
        form = super(EmployeeAdmin, self).get_form(request, *args, **kwargs)
        form.request = request        
        return form



    def save_model(self, request, obj, form, change):
        if change:
            old_obj = Employee.objects.get(id=obj.id)
            if obj.jobtitle != old_obj.jobtitle:
                employee_detail_change_notification(obj, 'job title', obj.jobtitle.name)
            if obj.line_manager != old_obj.line_manager:
                employee_detail_change_notification(obj, 'line manager', obj.line_manager)
            if obj.acting_line_manager != old_obj.acting_line_manager:
                employee_detail_change_notification(obj, 'acting line manager', obj.acting_line_manager)
            if obj.home_address_line1 != old_obj.home_address_line1 or \
               obj.home_address_line2 != old_obj.home_address_line2 or\
               obj.home_address_line3 != old_obj.home_address_line3 or\
               obj.home_address_city != old_obj.home_address_city or\
               obj.home_address_postcode != old_obj.home_address_postcode or\
               obj.home_address_country != old_obj.home_address_country or\
               obj.home_address_phone != old_obj.home_address_phone or\
               obj.personal_email != old_obj.personal_email:
                new_address = '%s\n%s\n%s\n%s\n%s\n%s\n\nPhone: %s\nEmail: %s' %(
                    obj.home_address_line1,
                    obj.home_address_line2,
                    obj.home_address_line3,
                    obj.home_address_city,
                    obj.home_address_postcode,
                    obj.get_home_address_country_display(),
                    obj.home_address_phone,
                    obj.personal_email,
                )
                employee_detail_change_notification(obj, 'home address details', new_address)
            if obj.marital_status != old_obj.marital_status:
                employee_detail_change_notification(obj, 'marital_status', obj.get_marital_status_display())
        obj.save()

admin.site.register(Employee, EmployeeAdmin)

这有什么帮助吗?

最佳答案

Admin 找不到 user_name 的原因是 user_name 字段未在类级别的自定义表单上定义。它仅在 __init__ 中定义.当管理员检查表单的可用字段时,它只能访问该类,而不是初始化的表单。所以检查表单类并没有显示 user_name 可用。

直接在类级别定义所有字段而不是表单的 __init__方法。如果您不需要所有情况下的所有字段,则根据需要从 __init__ 中的表单字段字典中删除字段。需要的方法。

您也可以反向执行此操作 - 将员工信息添加到用户编辑页面?这可以按照 https://docs.djangoproject.com/en/1.4/topics/auth/#adding-userprofile-fields-to-the-admin 中的说明完成。 .

最后,您似乎已经到了在不使用 Admin 的情况下实现您想要的功能可能更容易的阶段——虽然 Django 的 Admin 确实有很多可扩展性功能,但在某些时候编写您自己的实现将比使用 Admin 更容易。

关于django admin fieldsets - 添加相关模型的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24735252/

相关文章:

javascript - Django-动态表单增量ID为表单集中添加的每个新输入元素

python - 仅具有查看权限的 Django 模型表单将所有字段排除在外

django-admin - Django admin - 定义 list_editable 的动态方式

python - 如果已经有django项目,如何使用startproject(django-admin.py)?

python-3.x - 如何从 django admin 隐藏/取消注册 django-allauth 创建的帐户和社交帐户?

python - 如果找不到 Django 对象如何继续运行

django - 如何向 Django Celery Flower Monitoring 添加身份验证和端点?

python - 如何在不破坏标签的情况下截断 html?

python - 在 Django 表单中组合 ModelChoiceField 以保存在单个 ManyToManyField 中

django - 带有复选框的表单中的manytomany字段在django模板中安装了选择字段