首页 > 解决方案 > 如何通过将编辑前的实例与当前实例进行比较来编辑字段

问题描述

我目前正在尝试在对用户进行编辑时记录字段更改,但是,我正在努力将旧用户实例与当前用户实例进行比较并检索不同的字段。

到目前为止,在 for 循环中运行条件时,它会打印与模型相关的所有字段,而不是已编辑的字段。

我也在努力获得循环通过的字段的值。

方法:

def log_user_change(old_user_instance, request):

        user = User.objects.get(pk = old_user_instance.id)

        user_fields = user._meta.get_fields()
        old_user_fields = old_user_instance._meta.get_fields()

        ct = ContentType.objects.get_for_model(user)

        for old_user_fields in user_fields:
            if not old_user_fields in user_fields:

                field_values = getattr(old_user_instance, old_user_fields.attname)

                print('Changed field:')
                print(old_user_fields)
                print('Values:')
                print(field_values)

                """
                ChangeLog.objects.log_updae(
                    user = request,
                    content_type = ct.pk,
                    object_id = user.pk,
                    changes = user_fields,
                )
                """

看法:

def editUser(request, pk):

    # Query appropriate user based on pk returned in url
    user = User.objects.get(pk = pk)

    # Get the EditUserForm and add the user as instance
    edit_user_form = EditUserForm(instance = user)

    if request.method == 'POST':

        # Bind data to the form class, and add the user as instance
        edit_user_form = EditUserForm(request.POST, error_class=DivErrorList, instance = user)

        old_user_instance = User.objects.get(pk = pk)

        # Validate form inputs
        if edit_user_form.is_valid():

            # Save edits
            edit_user_form.save()


            # Log change
            ChangeLog.log_user_change(old_user_instance, request.user.id)

        else:
            # error

    context = {
        'user': user,
        'edit_user_form': edit_user_form,
    }

    # Render request, template and context
    return render(request, 'users/backend/user/user_edit.html', context)

标签: pythondjango

解决方案


您需要循环遍历User._meta.get_fields()模型上定义的所有字段,然后使用gettattr获取旧实例和新实例的值,然后比较它们

def log_user_change(old_user_instance):
    new_user_instance = User.objects.get(pk=old_user_instance.pk)
    for field in User._meta.get_fields():
        if isinstance(field, models.ManyToOneRel):
            continue
        old_value = getattr(old_user_instance, field.name)
        new_value = getattr(new_user_instance, field.name)
        if old_value != new_value:
            print('Changed field:', field.name)
            print('Old value:', old_value, 'New value:', new_value)

推荐阅读