Как создать собственный метод сохранения для существующего поля m2m. (Джанго) - PullRequest
0 голосов
/ 09 марта 2019
  • У меня есть модель профиля, которая содержит образование и создала отношение многие ко многим, то есть многие профили могут иметь много образований.
  • У меня есть шаблон под названием Настройки профиля, который содержит несколько форм, таких как Education CreateView,Образование UpdateView и Образование 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'}),
        }

URL

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 Ответ

1 голос
/ 09 марта 2019

Вам нужно передать текущего пользователя или запрос в экземпляр 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?

...