如何为现有的m2m字段创建自定义保存方法。 (Django)

时间:2019-03-09 07:33:04

标签: python django django-models django-forms

  • 我有一个配置文件模型,其中包含教育并创建了许多 许多关系,即许多个人资料可以接受许多教育。
  • 我有一个名为“个人档案设置”的模板,其中包含多个表格,例如Education CreateView,Education UpdateView和Education ListView。我正在使用引导程序模式来显示这些形式。因此,它们共享相同的模板。
  • 问题是每当我保存教育表格时,它将表格保存在数据库中 并在该个人资料的教育选择字段中显示 Django的管理员,但未选中,它不会创建之间的M2M链接 个人资料和教育。
  • 我重写了save()方法来创建社区建议的链接,但是我无法获取当前的配置文件。保存后出现此错误。 (“ EducationForm”对象没有属性“ request”)

模型

class Profile(models.Model):
    phone         = models.CharField(max_length=11, null=True, blank=True)
    education     = models.ManyToManyField(Education, null=True, blank=True, related_name="education")
    full_name     = models.CharField(max_length=30, null=True, blank=True)

class Education(models.Model):
    degree      = models.CharField(max_length=100, null=True, blank=True)
    school      = models.CharField(max_length=100, null=True, blank=True)
    edu_start_date  = models.DateField(null=True, blank=True)
    edu_end_date    = models.DateField(null=True, blank=True)

查看

class EducationView(CreateView):
    model = Education
    form_class = EducationForm
    pk_url_kwarg = 'pk'
    template_name = "profile_settings.html"

class ProfileSettingsView(UpdateView):
    model = Profile
    form_class = ProfileSettingsForm
    pk_url_kwarg = 'pk'
    context_object_name = 'object'
    template_name = 'profile_settings.html'

    def get_success_url(self):
          return reverse_lazy('users:profile_settings', args = (self.object.id,))

    def get_object(self):
        pk = self.kwargs.get('pk')
        return get_object_or_404(Profile, id=pk)

    def get_context_data(self, **kwargs):
        context = super(ProfileSettingsView, self).get_context_data(**kwargs)
        context['prof'] = self.get_object()
        return context

表格

class EducationForm(forms.ModelForm):

    degree = forms.CharField(max_length=40, required=False)
    school = forms.CharField(max_length=40, required=False)
    edu_start_date = forms.DateField(required=False,
                                     input_formats=settings.DATE_INPUT_FORMATS,
                                     widget=forms.DateInput(attrs={'readonly': 'readonly'}))
    edu_end_date = forms.DateField(required=False,
                                   input_formats=settings.DATE_INPUT_FORMATS,
                                   widget=forms.DateInput(attrs={'readonly': 'readonly'}))

    def save(self, commit=True):
        edu = super(EducationForm, self).save(commit=False)
        edu.save()
        profile = Profile.objects.get(self.request.user.profile.id)
        profile.education.add(education=edu)

        return edu


    class Meta:
        model = Education

        fields = ['degree','school','edu_start_date','edu_end_date']

class ProfileSettingsForm(forms.ModelForm):
    class Meta:
        model = Profile

        fields = ['phone','full_name','education']

        widgets = {

            'full_name': forms.TextInput({'class': 'form-control'}),
            'phone': forms.TextInput({'class': 'form-control'}),
        }

网址

urlpatterns = [
path('<int:pk>/education/update/', views.EducationUpdate.as_view(), name='education_update'),
path('<int:pk>/profile/settings', views.ProfileSettingsView.as_view(), name='profile_settings'),
    ]

模板(Profile_settings.html)

<form action="#" style="padding-left: 15px; padding-right:15px;" method="POST">
        {{ form.errors }}
        {% csrf_token %}
    <div class="row">
        <div id="education_update" class="modal fade" role="dialog">
          <div class="modal-dialog">

            <div class="modal-content">
              <div class="modal-header">
                  <h4 class="modal-title">New Education</h4>
                <button type="button" class="close" data-dismiss="modal">&times;</button>
              </div>
              <div class="modal-body">
                <div class="row">
                <div class="col-lg-12">
                    <div class="form-group">
                        <div class="field">
                            <label>Degree title<span class="red-txt">*</span></label>
                            <!-- <input class="form-control" type="text" name="degree" value="" maxlength="60" size="50"> -->
                            {{ edu_object.degree }}
                        </div>
                    </div>
                </div>
                <div class="col-lg-12">
                    <div class="form-group">
                        <div class="field">
                            <label>School<span class="red-txt">*</span></label>
                            <!-- <input class="form-control" type="text" name="school" value="" maxlength="60" size="50"> -->
                            {{ edu_object.school }}
                        </div>
                    </div>
                </div>

                <div class="col-lg-6">
                    <div class="form-group">
                        <div class="field">
                            <label>Start date</label>
                            <div id="datepicker1" class="datepicker input-group date" data-date-format="yyyy-mm-dd">
                                {{ edu_object.edu_start_date }}
                                <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="col-lg-6">
                    <div class="form-group">
                        <div class="field">
                            <label>End date</label>
                            <div id="datepicker2" class="datepicker input-group date" data-date-format="yyyy-mm-dd">
                                {{ edu_object.edu_end_date }}
                                <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="col-lg-12">
                    <br>

                    <div style="text-align:center;" class="login login-button">
                        <input type="submit" class="btn btn-outline-primary btn-lg" style="cursor: pointer;" value="Save">
                    </div>
                </div>
            </div>
              </div>
            </div>

          </div>
        </div>
    </div>
</form>


{% if prof %}
<table class="table">
    <tbody>
        {% for edu in prof.education.all %}
            <tr class="divbutton" style="height: 90px;">
                <td>
                    <div class="row">
                        <div style="padding-left: 40px; font-size: 20px;">{{ edu.degree }}</div>
                        <div style="padding-left: 40px; font-size: 20px;">{{ edu.school }}</div>
                    </div>
                </td>
                <td class="align-middle">
                    <div class="row">
                        <div id="button_under" style="margin-right: 20px;" class="login login-button">
                            <a href="#" class="btn btn-info" data-toggle="modal" data-target="#education_update" data-backdrop="false"><i class="fa fa-edit"></i> Edit</a>
                        </div>
                        <div id="button_under" class="login login-button">
                            <a href="" class="btn btn-danger"><i class="fa fa-trash"></i> Delete</a>
                        </div>
                    </div>
                </td>
            </tr>
        {% endfor %}
        {% endif %}
    </tbody>
</table>

1 个答案:

答案 0 :(得分:1)

您需要将当前用户或请求传递给Form实例,以便可以在get_form_kwargs中覆盖EducationView

def get_form_kwargs(self):
    kwargs = super(EducationView, self).get_form_kwargs()
    kwargs['request'] = self.request
    return kwargs

然后像这样初始化EducationForm

def __init__(self, request,  *args, **kwargs):
    super(EducationForm, self).__init__(*args, **kwargs)
    self.request = request

顺便说一句,related_name中的Profile字段不应该是profiles吗?