【问题标题】:How to get all form field data in Django UpdateView when working with many-to-many model field?使用多对多模型字段时如何在 Django UpdateView 中获取所有表单字段数据?
【发布时间】:2021-09-25 14:08:08
【问题描述】:

由于某种原因,我的 UpdateView 没有显示选定的关联。该表单仅预填充了第一个表单字段数据结果、用户名,而没有其他字段数据。我怀疑这是由于查询了 ManytoMany 字段。我已经搜索并尝试了可能的解决方案,但没有任何效果。有什么想法吗?

Models.py

class Company(models.Model):
    """All company specific details. For each main manager, a company is created. The main manager can then add company members, creating for them their user accounts."""
    members = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='teams', through='CompanyMembership'
    )
    ...

class CompanyMembership(models.Model):
    """Acts as a gateway between User model and Company model"""
            STAFF = "STAFF", "Staff"
            MANAGERS = "MANAGERS", "Managers"
    my_company = models.ForeignKey(Company, on_delete=models.CASCADE)
    my_identity = models.ForeignKey(User, on_delete=models.CASCADE)
    my_role = models.CharField(max_length=100, choices=MemberTypes.choices, default=None)

class User(models.Model):
    """Users can be main managers or staff. Each main manager has their own Company. Many staff can belong to a single Company associated with a main manager."""
    username = models.CharField(_("Login Name"), blank=True, null=True, max_length=155, unique=True)
    ...
Views.py

class TeamMembersView(LoginRequiredMixin, CompanyMembershipCheckMixin, UserPassesTestMixin, ListView):
    """Lists all the company team members for the specific company"""
    model = Company
    template_name = 'users/dashboard/team.html'

    def test_func(self):
        user_obj = User.objects.get(id=self.request.user.id)
        return user_obj.groups.filter(name='Company_Main_Manager').exists()

    def get_context_data(self, **kwargs):
        context = super(TeamMembers, self).get_context_data(**kwargs)
        user_obj = User.objects.get(id=self.request.user.id)
        companymembership_obj = CompanyMembership.objects.get(my_identity=user_obj)
        company_obj = Company.objects.get(id=companymembership_obj.my_company.id)
        slug = company_obj.slug
        context['members'] = ecosystem_obj.members.all()
        context['slug'] = slug
        return context

class TeamMemberUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    """Allows the main manager to change or update the specific staff member's user data"""
    model = User
    template_name = 'users/dashboard/user_create.html'
    form_class = TeamMemberCreateForm

    def test_func(self):
        user_obj = User.objects.get(id=self.request.user.id)
        return user_obj.groups.filter(name='Company_Main_Manager').exists()

    def get_context_data(self, **kwargs):
        data = super(TeamMemberUpdateView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['member'] = TeamMemberCreateForm(self.request.POST, self.request.FILES)
        else:
            data['member'] = TeamMemberCreateForm()
        return data
   
    def form_valid(self, form):
        context = self.get_context_data()
        member = context['member']
        with transaction.atomic():
            form.instance.created_by = self.request.user
            self.object = form.save()
            if member.is_valid():
                member.instance = self.object
                member.save()
        return super(TeamMemberUpdateView, self).form_valid(form)

Forms.py
class TeamMemberCreateForm(ModelForm):
    """Allows the main manager to create (and update) a user account for additional staff members."""
    first_name = forms.CharField(max_length=200, help_text="Enter member's first name", required=True)
    last_name = forms.CharField(max_length=200, help_text="Enter member's last name")
    email = forms.EmailField(max_length=200, help_text="Member's primary email address")
    phone = forms.CharField(max_length=100, help_text="Primary phone number")
    position_title = forms.CharField(max_length=200, help_text="Member's job position or title for the company")

    class Meta(UserCreationForm.Meta):
        model = User
        exclude = ['company_name']

    @transaction.atomic
    def save(self):
        member_user = super().save(commit=False)
        member_user.firstname = self.cleaned_data.get('first_name')
        member_user.lastname = self.cleaned_data.get('last_name')
        member_user.email = self.cleaned_data.get('email')
        member_user.phone = self.cleaned_data.get('phone')
        member_user.is_company_main_manager = False
        member_user.is_active = True
        member_user.user_type = User.UserTypes.STAFF
        member_user.save()
        CompanyMembership.objects.create(my_company=ecosystem_create, my_identity=user, my_role=CompanyMembership.MemberTypes.STAFF)
        return member_user

例如,如果我是主要经理,我可以通过上述表格为我的员工创建一个用户帐户。对于员工帐户,我输入 username="username_example"、first_name="pete"、last_name="smith"、phone="333-333-3333",... 等等。 CreateView 按预期工作。用户帐户已创建、保存等。不过,UpdateView 将显示在此示例中:

    username: username_example
    first name: 
    last name: 
    phone: 
    ... 
   # The first field of the form is pre-populated but none of the others... why?

【问题讨论】:

    标签: django django-models django-views django-forms django-orm


    【解决方案1】:

    你必须超级初始化你的表单并用

    重写字段

    def init(self, *args, **kwargs):

    super(TeamMemberCreateForm, self).__init__(*args, **kwargs)
    
    self.fields[your_field] = forms.ModelMultipleChoiceField(
                               queryset=Company.objects.all(),  
                               widget=forms.CheckboxSelectMultiple(attrs=
                         {'dir': 'ltr', 'type': "checkbox",'switch':"bool"}))
    

    【讨论】:

    • 感谢您的帮助。我不太确定你的意思。在 UpdateView 中调用 super?我最初是在 get_context_data 方法下这样做的,但似乎没有什么不同。我最初也尝试以相同的方法将数据分配给字段,但它也没有做任何事情。
    【解决方案2】:

    通过在UpdateView中使用fields = ['username', 'firstname', 'lastname', 'email', 'phone']而不是form_class = TeamMemberCreateForm,问题解决了。

    【讨论】:

      猜你喜欢
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2016-08-11
      相关资源
      最近更新 更多