Множество значений в Form_valid

#python #django

#python #django

Вопрос:

У меня есть 2 модели, которые связаны с ManyToMany

 class Prestaciones(TimeStampedModel):
    nombre = models.CharField('Prestanciónes', max_length=35)
    prestacion = models.ManyToManyField(PrestacionIndi)
    turno = models.ForeignKey(Turno, on_delete=models.PROTECT)
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    activo = models.BooleanField(default=True)

class PrestacionIndi(TimeStampedModel):
    nombre = models.CharField('Prestanción', max_length=35)
    num_dias = models.IntegerField('Dias',)
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    activo = models.BooleanField(default=True)
  

PrestacionesForm:

 class PrestacionesForm(forms.ModelForm):
    class Meta:
        model = Prestaciones
        fields = (
            'nombre',
            'prestacion',
            'activo',
            'turno',
        )
        widgets = {
        'nombre': forms.TextInput(
            attrs={
                'placeholder': 'Nombre',
                'class': 'form-control'
            }
        ),
        'prestacion': forms.SelectMultiple(
            attrs={
                'placeholder': 'Prestaciones',
                'class': 'form-control'
            }
        ),
        'turno': forms.Select(
            attrs={
                'placeholder': 'Nombre',
                'class': 'form-control'
            }
        )
    }
  

Вид:

 class PrestacionesCreateview(FormView):
    template_name = 'admins/form_prestaciones.html'
    form_class = PrestacionesForm
    success_url = reverse_lazy('admins_app:prestaciones')

    def form_valid(self, form):
        nombre = form.cleaned_data['nombre']
        prestacion = form.cleaned_data['prestacion']
        turno = form.cleaned_data['turno']
        user = self.request.user
        obj, created = Prestaciones.objects.get_or_create(
            nombre = nombre,
            user = user,
            prestacion = prestacion,
            turno = turno
        )
        return super(PrestacionesCreateview, self).form_valid(form)
  

Ошибка:

 [03/Nov/2020 08:13:38] "GET /catalogo/prestaciones/crear/ HTTP/1.1" 200 8229
Internal Server Error: /catalogo/prestaciones/crear/
Traceback (most recent call last):
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/views/generic/edit.py", line 142, in post
    return self.form_valid(form)
  File "/home/erick/Escritorio/Proyectos/siap/applications/admins/views.py", line 422, in form_valid
    obj, created = Prestaciones.objects.get_or_create(
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/query.py", line 573, in get_or_create
    return self.get(**kwargs), False
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/query.py", line 425, in get
    num = len(clone)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/query.py", line 269, in __len__
    self._fetch_all()
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/query.py", line 1308, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/query.py", line 53, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1143, in execute_sql
    sql, params = self.as_sql()
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 513, in as_sql
    where, w_params = self.compile(self.where) if self.where is not None else ("", [])
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 430, in compile
    sql, params = node.as_sql(self, self.connection)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/sql/where.py", line 81, in as_sql
    sql, params = compiler.compile(child)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 430, in compile
    sql, params = node.as_sql(self, self.connection)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/fields/related_lookups.py", line 132, in as_sql
    return super().as_sql(compiler, connection)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/lookups.py", line 302, in as_sql
    return super().as_sql(compiler, connection)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/lookups.py", line 181, in as_sql
    rhs_sql, rhs_params = self.process_rhs(compiler, connection)
  File "/home/erick/Escritorio/enviroments/siap/lib/python3.8/site-packages/django/db/models/lookups.py", line 284, in process_rhs
    raise ValueError(
ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing.
  

При сохранении он помечает ошибку, поскольку не может сохранить несколько значений.

Я думаю, что моя проблема будет в области form_valid, поскольку она только получает значение и не повторяет значения

Я помещаю ошибку, когда пытаюсь сохранить manytomany, а также форму

Комментарии:

1. Пожалуйста, добавьте полную обратную трассировку ошибок….

2. редактировать с ошибкой, я все еще думаю, что это из-за того, что не используется для

3. Прежде всего, это не полная трассировка ошибок. Пожалуйста, добавьте полную обратную трассировку ошибок . Кроме того, добавьте соответствующее представление

4. Можете ли вы показать нам PrestacionesForm ?

5. я редактирую с ошибкой и формой

Ответ №1:

При работе с отношениями обе стороны должны существовать, прежде чем связь может быть установлена. Таким образом, нам нужно сначала создать объект Prestaciones, а затем добавить к нему выбранный Indi:

 class PrestacionesCreateview(LoginRequiredMixin, FormView):
    template_name = "main/form_prestaciones.html"
    form_class = PrestacionesForm
    success_url = reverse_lazy('admins_app:prestaciones')

    def form_valid(self, form):
        nombre = form.cleaned_data["nombre"]
        prestacion = form.cleaned_data["prestacion"]
        turno = form.cleaned_data["turno"]
        user = self.request.user
        obj, created = Prestaciones.objects.get_or_create(
            nombre=nombre, user=user, turno=turno
        )
        for item in prestacion:
            obj.prestacion.add(item)

        return super(PrestacionesCreateview, self).form_valid(form)
  

Комментарии:

1. спасибо, он отлично работает, не используя так много строк кода

Ответ №2:

Ошибка сообщает вам, что ваш get_or_create возвращает более одного. Вам нужно будет изменить PrestacionesCreateview.form_valid() , чтобы компенсировать.

 class PrestacionesCreateview(FormView):
    template_name = 'admins/form_prestaciones.html'
    form_class = PrestacionesForm
    success_url = reverse_lazy('admins_app:prestaciones')

def form_valid(self, form):
    nombre = form.cleaned_data['nombre']
    prestacion = form.cleaned_data['prestacion']
    turno = form.cleaned_data['turno']
    user = self.request.user

    obj_qs = Prestaciones.objects.filter(
        nombre = nombre,
        user = user,
        prestacion = prestacion,
        turno = turno
    )

    if obj_qs.count() == 0:
        # create
        obj = Prestaciones.objects.create(
            nombre = nombre,
            user = user,
            prestacion = prestacion,
            turno = turno
        )
    elif obj_qs.count() == 1:
         # get
         obj = obj_qs.first()
    else:
        # you'll have to decide how you want to handle multiples.
        obj = obj_qs.first()  #?


    return super(PrestacionesCreateview, self).form_valid(form)