【问题标题】:How do create a custom save method for an existing m2m field. (Django)如何为现有的 m2m 字段创建自定义保存方法。 (姜戈)
【发布时间】:2019-07-31 04:28:46
【问题描述】:
  • 我有一个包含教育的配置文件模型并创建了许多 许多关系,即许多个人资料可以有许多教育。
  • 我有一个名为 Profile settings 的模板,其中包含多个表单,例如 Education CreateView、Education UpdateView 和 Education ListView。我正在使用引导模式来显示这些表单。因此,它们共享相同的模板。
  • 问题是每当我保存教育表格时,它都会将表格保存在数据库中 它显示在该配置文件的教育多选字段中 django admin 但未选中,它不会在两者之间创建 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>

【问题讨论】:

    标签: python django django-models django-forms


    【解决方案1】:

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

    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
    

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

    【讨论】:

    • 收到此错误:Request Method: POST Request URL: http://localhost:8000/users/education/create/ Exception Type: TypeError at /users/education/create/ Exception Value: cannot unpack non-iterable int object 保存 193 中的文件“C:\Users\HP\Desktop\Crowdsocial\users\forms.py”。profile = Profile.objects.get(self.request. user.profile.id)`
    • 您需要将字段名称传递给filter(),例如,profile = Profile.objects.get(id=self.request.user.profile.id)
    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 2019-01-29
    • 2014-09-20
    相关资源
    最近更新 更多