Как разместить пустое поле ForeignKey в Django? - PullRequest
0 голосов
/ 25 октября 2019

Я довольно новичок в этом. У меня есть приложение, которое в основном представляет собой форму регистрации заезда / отъезда. Форма имеет 3 поля, два из которых являются обязательными, а другое - необязательным. Одним из обязательных полей в «Области» и единственным необязательным полем является «Станция», потому что не в каждой области есть станция, поэтому иногда не будет выбора для выбора станции. В настоящее время он работает нормально, если вы заполните все 3 поля, но не, если станция пуста, даже если в области нет станции.

Я получаю эту ошибку: ValueError: invalid literal for int() with base 10: ''

Я почти уверен, что проблема заключается в моем views.py, в одном из моих операторов if для обоих входов / выходов, потому что это происходит в обоих действиях, но я не уверен, что именно это может быть. Смысл этих утверждений if состоит в том, что:

Если человек вошел в область и забыл покинуть ее, а затем вошел в другую область, программа создаст новую запись и не коснется предыдущей записи области после того, как человек покинет область. новая зона (человек может входить и выходить из одной и той же зоны / станции несколько раз), поэтому, когда он покидает зону, самая последняя запись будет изменена только одна. Это аналогичная концепция для области выхода, и многие фильтры, которые я добавил, заключаются в том, что предыдущие записи не изменяются, поскольку .update () является массовым обновлением всего, что осталось после фильтра, а не только самых последних.

models.py

class WorkArea(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class StationNumber(models.Model):
    work_area = models.ForeignKey(WorkArea, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class EmployeeWorkAreaLog(models.Model):
    employee_number = models.IntegerField(max_length=50, help_text="Employee #", blank=False)
    work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False, help_text="Work Area", related_name="work_area")
    station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True, help_text="Station", related_name="stations", blank=True)
    time_in = models.DateTimeField(help_text="Time in", null=True, blank=True)
    time_out = models.DateTimeField(blank=True, help_text="Time out", null=True)

    def __str__(self):
        return self.employee_number

forms.py

class WarehouseForm(AppsModelForm):
    class Meta:
        model = EmployeeWorkAreaLog
        fields = ('employee_number', 'work_area', 'station_number')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['station_number'].queryset = StationNumber.objects.none()

        if 'work_area' in self.data:
            try:
                work_area_id = int(self.data.get('work_area'))
                self.fields['station_number'].queryset = StationNumber.objects.filter(work_area_id=work_area_id).order_by('name')
            except (ValueError, TypeError):
                pass
        elif self.instance.pk:
            self.fields['station_number'].queryset = self.instance.work_area.stations.order_by('name')

views.py

class EnterExitArea(CreateView):
    model = EmployeeWorkAreaLog
    template_name = "operations/enter_exit_area.html"
    form_class = WarehouseForm

    def form_valid(self, form):
        emp_num = self.request.POST['employee_number']
        area = self.request.POST['work_area']
        station = self.request.POST['station_number']

        if 'enter_area' in self.request.POST:
            form.save()
            if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)).filter(Q(station_number=station) | Q(station_number__isnull=True)):
                EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)).update(time_in=datetime.now())

            return HttpResponseRedirect(self.request.path_info)

        elif 'leave_area' in self.request.POST:
            if EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, work_area=area, station_number=station, time_out__isnull=True):
                recent = EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, work_area=area, station_number=station, time_out__isnull=True).latest('time_in').time_in
                EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, work_area=area, station_number=station, time_out__isnull=True, time_in=recent).update(time_out=datetime.now())
                return HttpResponseRedirect(self.request.path_info)

            form.save()
            EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, work_area=area, station_number=station).update(time_out=datetime.now())
            return HttpResponseRedirect(self.request.path_info)


def load_stations(request):
    work_area_id = request.GET.get('work_area')
    stations = StationNumber.objects.filter(work_area_id=work_area_id).order_by('name')
    return render(request, 'operations/station_number_dropdown_options.html', {'stations': stations})

TRACEBACK

Internal Server Error: /operations/enter-exit-area/
Traceback (most recent call last):
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\edit.py", line 172, in post
    return super().post(request, *args, **kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\edit.py", line 142, in post
    return self.form_valid(form)
  File "C:\Users\mkusneco\apps.rsrgroup.com\apps\operations\views.py", line 24, in form_valid
    if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)).filter(Q(station_number=station) | Q(station_number=None)):
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\query.py", line 844, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\query.py", line 862, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py", line 1263, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py", line 1281, in _add_q
    current_negated, allow_joins, split_subq)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py", line 1287, in _add_q
    split_subq=split_subq,
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py", line 1225, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py", line 1096, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\lookups.py", line 20, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\fields\related_lookups.py", line 115, in get_prep_lookup
    self.rhs = target_field.get_prep_value(self.rhs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\fields\__init__.py", line 965, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: ''
[25/Oct/2019 11:21:47] "POST /operations/enter-exit-area/ HTTP/1.1" 500 172567

1 Ответ

1 голос
/ 25 октября 2019

У вас есть форма, но вы игнорируете ее. Форма с готовностью преобразует все необработанные опубликованные данные в соответствующие типы, в частности, конвертирует целочисленный идентификатор, который вы получаете для station_number, в фактический экземпляр StationNumber. Но вы не используете cleaned_data формы;вместо этого вы возвращаетесь к необработанному ПОСТУ. Не делай этого.

Это должно быть:

    def form_valid(self, form):
        emp_num = form.cleaned_data['employee_number']
        area = form.cleaned_data['work_area']
        station = form.cleaned_data['station_number']
        ...
...