Python Django加载表单,其中包含从模型填充的数据

Python Django加载表单,其中包含从模型填充的数据,python,django,python-3.x,django-models,django-views,Python,Django,Python 3.x,Django Models,Django Views,我正在从事一个使用Python(3.7)和Django(2.3)的项目,在这个项目中,我通过扩展基本用户模型实现了多种类型的用户,现在我需要创建一个UserEdit页面,允许工作人员编辑用户 以下是我的模型: class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(max_length=254, unique=True) name = models.CharField(max_length

我正在从事一个使用Python(3.7)和Django(2.3)的项目,在这个项目中,我通过扩展基本用户模型实现了多种类型的用户,现在我需要创建一个UserEdit页面,允许工作人员编辑用户

以下是我的模型:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=255)
    title = models.CharField(max_length=255, choices=TITLE, blank=False)
    user_type = models.CharField(max_length=255, choices=USER_TYPE, blank=False)
    gender = models.CharField(max_length=255, choices=CHOICES, blank=False)
    contenst = models.CharField(max_length=255, blank=True, null=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    email_status = models.CharField(max_length=50, default='nc')

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['password']

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)

    def __str__(self):
        return str(self.email)


class PersonalBelow18(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='profile')
    dob = models.DateField(blank=False)
    customer_id = models.IntegerField(blank=False, verbose_name='Connect other User')
    collection_use_personal_data = models.BooleanField(blank=False)
    reference_identities = models.ForeignKey(Identities, blank=False, on_delete=models.CASCADE, related_name='refs')

    def __str__(self):
        if self.user.email is None:
            return "ERROR-CUSTOMER NAME IS NULL"
        return str(self.user.email)

    GRAPPELLI_AUTOCOMPLETE_SEARCH_FIELDS = {
        "myapp": {
            "MyFile": ("user__email__icontains",)
        }
    }


class PersonalAbove18(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    dob = models.DateField(blank=False)
    customer_id = models.IntegerField(blank=False, verbose_name='Connect other User')
    contact_email = models.EmailField(max_length=255, blank=False)
    reference_identities = models.ForeignKey(Identities, blank=False, on_delete=models.CASCADE)
    contact_no = PhoneNumberField(blank=True, null=True, max_length=13,
                                  help_text='Phone number must be entered in the'
                                            'format: \'+999999999\'. Up to 13 digits allowed.')

    collection_use_personal_data = models.BooleanField(blank=False)

    def __str__(self):
        print(type(self.user.email))
        if self.user.email is None:
            return "ERROR-CUSTOMER NAME IS NULL"
        return str(self.user.email)


class ContactPerson(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    contact_email = models.EmailField(blank=False)
    customer_id = models.BigIntegerField(blank=True)
    contact_no = PhoneNumberField(blank=True, null=True, help_text='Phone number must be entered in the'
                                                                   'format: \'+999999999\'. Up to 15 digits allowed.')
    collection_use_personal_data = models.BooleanField(blank=False)


class GroupContact(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    contact_email = models.EmailField(blank=False)
    customer_id = models.BigIntegerField(blank=False)
    contact_no = PhoneNumberField(blank=True, help_text='Phone number must be entered in the'
                                                        'format: \'+999999999\'. Up to 15 digits allowed.')
    department = models.CharField(max_length=255, blank=False)
    address = models.CharField(max_length=255, blank=False)
这是我的表格:

class UserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ('email', 'name', 'password1', 'password2', 'title',
                  'gender', 'contenst', 'user_type')

   class Below18Form(forms.ModelForm):
    class Meta:
        model = PersonalBelow18
        widgets = {'dob': DateInput()}
        fields = ('dob', 'customer_id', 'collection_use_personal_data')

class Above18Form(forms.ModelForm):
    class Meta:
        model = PersonalAbove18
        widgets = {'dob': DateInput()}
        fields = ('dob', 'customer_id',
                  'contact_email',
                  'contact_no', 'collection_use_personal_data')

class UserCPForm(forms.ModelForm):
    class Meta:
        model = ContactPerson
        fields = ('contact_email', 'contact_no', 'collection_use_personal_data')

class GroupContactForm(forms.ModelForm):
    class Meta:
        model = GroupContact
        fields = ('contact_email', 'contact_no', 'department', 'address')
以下是我用来组合多种表单的方法:

以下是我的观点:

class EditUserDashboard(generic.DetailView):
    def get(self, request, *args, **kwargs):
        id = self.kwargs['id']
        try:
            u = User.objects.get(id=id)
            print(u.user_type)
            u_form = UserForm(request.POST, instance=u)
            if u.user_type == 'PB':
                p = PersonalBelow18.objects.get(user_id=id)
                p_form = Below18Form(request.POST, instance=p)
                return render(request, 'dashboard/user_edit.html', {'u_form': u_form,
                                                                    'p_form': p_form,
                                                                    'u': u})
            elif u.user_type == 'PA':
                p = PersonalAbove18.objects.get(user_id=id)
                p_form = Above18Form(request.POST, instance=p)
                return render(request, 'dashboard/user_edit.html', {'u_form': u_form,
                                                                    'p_form': p_form,
                                                                    'u': u})
            elif u.user_type == 'ContactPerson':
                p = ContactPerson.objects.get(user_id=id)
                print(p.user.id)
                p_form = UserCPForm(request.POST, instance=p)
                return render(request, 'dashboard/user_edit.html', {'u_form': u_form,
                                                                    'p_form': p_form,
                                                                    'u': p})
            elif u.user_type == 'GC':
                p = GroupContact.objects.get(user_id=id)
                p_form = GroupContactForm(request.POST, instance=p)
                return render(request, 'dashboard/user_edit.html', {'u_form': u_form,
                                                                    'p_form': p_form,
                                                                    'u': u})
            else:
                print('something else')
        except Exception as e:
            print(e)
            pass
更新:我的HTML表单:


{%csrf_令牌%}
{{u|u形|脆}}
{{p|u形|脆}}
更新
当我加载编辑页面时,它返回错误为:

“联系人”对象不可订阅

内部服务器错误:/dashboard/user/10/编辑回溯(最新) 调用最后一个文件 “/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/django/core/handlers/exception.py”, 第34行,在内部 response=get_response(请求)文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/django/core/handlers/base.py”, 第126行,在“获取”响应中 “未返回任何。”%(回调。模块,视图名称)值错误:视图仪表板.views.EditUserDashboard未返回 HttpResponse对象。它没有返回任何结果。[2019年12月21日 20:07:16]“GET/dashboard/user/10/edit HTTP/1.1”500 53502


您可以尝试以下操作:

p = ContactPerson.objects.get(user__id=id)  # instead of user_id=id


@roganjosh我添加了视图,错误出现在对
EditUserDashboard
Yep的get请求上。如果您的
尝试在
类EditUserDashboard(generic.DetailView)中失败,会发生什么情况:
?您的
异常除外as e
应该在控制台中打印一些内容,并且您返回
是的,我的异常语句正在打印:
'ContactPerson'对象不可订阅
@roganjosh我已经在
forms.py
视图
中更新了表单,现在它正在按get请求加载表单,但有空字段,它应该加载有填充数据的字段。@roganjosh请参阅,我已将语句更改为
p=ContactPerson.objects.get(user\u id=id)
,但仍然存在相同的错误。我已在
forms.py
视图中更新表单,现在它正在按get请求加载表单,但是如果字段为空,它应该加载包含填充数据的字段。很好,请在user_edit.html中显示相关的代码段。我已经添加了相关的html。为什么在一个表单标记中有两个单独的表单?这对我来说很奇怪。这就像你试图做一个表单集,它不接受预定义的实例,而是以一种不可理解的方式(至少我是这么认为的)。我的建议是现在去掉一个表单,只在视图和模板中使用p_表单,看看这是否有效,因为单个表单接受实例作为参数。如果我们的方法有效,您可能希望使用表单集在一个页面中预填充多个表单。这里有一个指向另一个ST答案的链接,它给出了实现这一点的良好概述。
p = ContactPerson.objects.get(user__id=id)  # instead of user_id=id
p = ContactPerson.objects.get(user=u)