Создание множества моделей за одну отправку - PullRequest
1 голос
/ 18 марта 2019

Я новичок в Джанго. Извините за мой плохой английский)

Есть 2 модели: 1. RelationType; 2. RequestRelation. Вторая модель связана с первой через MTM field.

Существует форма множественного выбора, основанная на списке «типов отношений». Необходимо создать несколько моделей, когда RequestRelation отправка, в зависимости от выбранных элементов multi-select?

F.e., если выбран "муж / жена / сын", необходимо создать 3 модели соответственно . Отличительными в них являются только типы взаимоотношений.

form.is_valid(), правильные значения приходят.

Но на данный момент создается только одна модель со списками всех выбранных типов отношений.

Также в моем коде есть ошибка. Модель создается сразу после загрузки страницы, а не после отправки.

Заранее спасибо.

models.py

class RelationType(models.Model):
    title = models.CharField(max_length=40)

    def __unicode__(self):
        return self.title

class RelationRequest(models.Model):
    creator = models.ForeignKey(User, related_name='creator')
    relation = models.ForeignKey(User, related_name='relation')
    type_of_relation = models.ManyToManyField(RelationType, related_name='type_relation',
        verbose_name=_('type_relation'))
    status = models.BooleanField(_('status'), default=False)

    created = models.DateTimeField(_('created'), auto_now_add=True)
    updated = models.DateTimeField(_('updated'), auto_now=True)

HTML

<form action="" method="POST" multiple="multiple">
    {% csrf_token %}
    {{ relation_form.type_of_relation }}
    <input type='submit' value='ok'>
</form>

forms.py

class RelationRequestForm(forms.ModelForm):
    class Meta:
        model = RelationRequest
        fields = ('type_of_relation',)
        widgets = {
            'type_of_relation': forms.SelectMultiple(
                attrs={
                    'class': 'select2',
                    'style': 'width: 235px',
                }
            ),
        }

    def __init__(self, *args, **kwargs):
        super(RelationRequestForm, self).__init__(*args, **kwargs)
        self.fields['type_of_relation'].empty_label = None
        self.fields['type_of_relation'] = forms.ModelMultipleChoiceField(queryset=RelationType.objects.all())

    def clean(self):
        type_of_relation = self.cleaned_data.get('type_of_relation')

views.py

def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        relation_form = RelationRequestForm(request.POST)
        if relation_form.is_valid():
            req_rel = relation_form.save(commit=False)
            req_rel.creator = request.user
            relation_user_id = int(filter(lambda x: x.isdigit(), request.path))
            req_rel.relation = User.objects.get(id = relation_user_id)
            req_rel.save()
            relation_form.save_m2m()
        context = self.get_context_data(relation_form = relation_form)
        return self.render_to_response(context)

обн. of views.py

@method_decorator(login_required, name='dispatch')
class ProfileView(DetailView):
    model = User
    queryset = User.objects.filter(is_active=True)

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        content_type = ContentType.objects.get_for_model(User)
        content_type_post = ContentType.objects.get_for_model(Post)
        posts = Post.objects.filter(
            enabled=True,
            for_content_type=content_type,
            for_object_id=self.object.id,
        )
        comments = Comment.objects.filter(
            content_type=content_type_post, object_id__in=posts.values_list('id')
        ).order_by('-id')
        posts = posts.prefetch_related(
            'from_content_type', 'for_content_type',
            'from_object', 'for_object',
            Prefetch('comments', queryset=comments),
        )
        if request.GET.get('page'):
            posts = posts.filter(
                created_at__lte=datetime.strptime(
                    request.GET.get('time'), '%Y%m%d%H%M%S'
                )
            )

        posts = paginator_factory(request, posts, 20)
        post_list = []
        for post in posts.object_list:
            comments = post.comments.all()[:3]
            comment_form = CommentForm(prefix=post.id)
            post_list.append({
                'post': post,
                'comment_form': comment_form,
                'comments': comments
            })
        form_set = formset_factory(PostImageForm, extra=1)
        form = PostForm()
        popup_search_form = PeoplePopupSearchForm()
        user_confirmeds = UserConfirm.objects.filter(
            sender=request.user, is_real=True
        ).count()
        accept_request_all = UserConfirm.objects.filter(
            recipient=request.user,
            sender__slug=kwargs.get('slug')
        )
        accept_request = accept_request_all.filter(is_real=True)
        not_accept_request = accept_request_all.filter(is_real=False)
        circle = UserCircle.objects.get_or_create(user=request.user)[0]
        circle_users = circle.users.all()
        post_next = posts.has_next()


        context = self.get_context_data(
            form=form,
            post_list=post_list,
            form_set=form_set,
            circle_users=circle_users,
            post_next=post_next,
            time=now(),
            popup_search_form=popup_search_form,
            user_confirmeds=user_confirmeds,
            accept_request=accept_request,
            not_accept_request=not_accept_request,
        )
        if request.is_ajax():
            template_ajax = render_to_string(
                template_name='communication/post_list.html',
                context={
                    'post_list': post_list,
                    'request': request
                }
            )
            return JsonResponse({
                'success': True,
                'template': template_ajax,
                'next': post_next,
            })
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        relation_form = RelationRequestForm(request.POST or None)
        if relation_form.is_valid():
            for rt in relation_form.cleaned_data['type_of_relation']:
                relation_user_id = int(filter(lambda x: x.isdigit(), request.path))
                rq = RelationRequest.objects.create(
                    creator = request.user,
                    relation = User.objects.get(id = relation_user_id),
                )
                rq.type_of_relation.add(rt)
        context = self.get_context_data(relation_form = relation_form)
        return self.render_to_response(context)

HTML визуализируется

<tr><th><label for="id_type_of_relation">Type of relation:</label></th><td><select name="type_of_relation" required multiple="multiple" id="id_type_of_relation">
  <option value="1" selected>Familliar</option>

  <option value="2">Mate</option>

  <option value="3" selected>Friend</option>

  <option value="4">Husband</option>

  <option value="5">Wife</option>

  <option value="6">Son</option>

  <option value="7">Daughter</option>

  <option value="8">Mother</option>

  <option value="9">Father</option>

  <option value="10">Sister</option>

  <option value="11">Brother</option>

  <option value="12">Grandmother</option>

  <option value="13">Grandfather</option>

  <option value="14">Granddaughter</option>

  <option value="15">Grandson</option>

  <option value="16">Relative</option>

  <option value="17">Colleague</option>

  <option value="18">Partner</option>

  <option value="19">Mentor</option>

  <option value="20">Pupil</option>

  <option value="21">Provider</option>

  <option value="22">Customer</option>

</select></td></tr>

1 Ответ

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

ModelForm связана с экземпляром Model, который вы указываете в своем мета-классе.form.save_m2m() позволяет создавать подключения m2m, но в вашем случае это создаст RelationType, и, насколько я понимаю, вы хотите создать RelationRequest экземпляров.

Я бы рекомендовал написать Form споле forms.ModelMultipleChoiceField(queryset=RelationType.objects.all()) и перебор пользовательского ввода для создания всех RelationRequest, необходимых вам в form.is_valid().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...