【问题标题】:Populate custom field in Django form以 Django 表单填充自定义字段
【发布时间】:2022-11-11 01:41:13
【问题描述】:

我希望用户能够更新他们的电子邮件地址。我创建了一个包含字段的配置文件,但电子邮件地址在用户表中。我创建了一个添加自定义表单字段的表单,它适用于更新。但是,我找不到在 REQUEST.GET 上预填充此字段的方法。

# forms.py

class ProfileForm(forms.ModelForm):
    
    class Meta:
        model = Profile
        fields = ('name', 'timezone')


class ProfileUpdateForm(ProfileForm):
    
    email = forms.EmailField(max_length=254)

    class Meta(ProfileForm.Meta):
        fields = ProfileForm.Meta.fields + ('email',)
# views.py

@login_required
@require_http_methods(["GET","POST"])
def profile_update_view(request):

    context = {}
    
    # Get the logged in users profile
    profile_object = Profile.objects.get(user=request.user.id)

    if request.method == 'GET':
        profile_form = ProfileUpdateForm(None, instance=profile_object)
        context["form"] = profile_form
        # how can I add User.objects.get(id=request.user.id).email to the custom field

    if request.method == 'POST':
        profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object)
        context["form"] = profile_form
        
        if profile_form.is_valid():
            try:
                # email address exists
                user = User.objects.get(email=profile_form.cleaned_data.get('email'))
                messages.error(request, 'Failed profile update. Email address already exists.')
            except:
                # email address available
                # get user object                
                user = User.objects.get(id=request.user.id)
                user.email = profile_form.cleaned_data.get('email')
                # update user object
                user.save()
                profile_form.save()
                messages.success(request, 'Successful profile update.')
            

    return render(request, "profile.html", context)

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    我倾向于支持基于类的观点,像这样的事情是他们自己的地方。表格:

    class ProfileUpdateForm(forms.ModelForm):
    
        class Meta:
            model = Profile
            fields = ('name', 'timezone')
    
        email = forms.EmailField(max_length=254) #add non-model form field
    

    以及基于类的视图。在 get_initial() 中处理 email 的初始值,并在 form_valid() 中更新 self.request.user:

    class ProfileUpdateView( UpdateView):
        model = Profile
        form_class = ProfileUpdateForm
        template_name = 'profile.html'  # profiles/update_profile.html would be better
        # other declarations ...?
          
    
        def get_initial(self):
            initial = super().get_initial()
            initial['email'] = self.request.user.email
            return initial
    
        # @transaction.atomic might be a good idea
        def form_valid(self,  form):
            new_email = form.cleaned_data['email']
            user = self.request.user
            if user.email != new_email:  # don't do a pointless non-update save
                 user.email = new_email
                 user.save()
            return super().form_valid( form)  # will save the profile
    

    【讨论】:

      【解决方案2】:
      # forms.py
      
          def __init__(self, *args, **kwargs):
              self.email = kwargs.pop("email")
              super(ProfileUpdateForm, self).__init__(*args, **kwargs)
              self.initial['email'] = self.email
      
      
      # views.py
      
          if request.method == 'GET':
              profile_form = ProfileUpdateForm(None, instance=profile_object, email=request.user.email)
              context["form"] = profile_form
      
          if request.method == 'POST':
              profile_form = ProfileUpdateForm(request.POST or None, instance=profile_object, email=request.POST.get('email'))
              context["form"] = profile_form
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-12
        • 2017-12-17
        • 2011-05-23
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多