<ForeignKey> не JSON сериализуемое Django приложение - PullRequest
0 голосов
/ 19 марта 2020

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

views.py

....
def PackingListView(request):
    if request.method == "POST":
        form = PackingListForm(request.POST)
        if form.is_valid():
            if 'preview' in request.POST:
                request.session['data'] = form.cleaned_data
                return redirect('myview')

            elif 'save' in request.POST:

                form.save()

                context = request.session['data'] = form.cleaned_data #get the from the form
                pdf = render_to_pdf('packlist_preview.html', context) #create the PDF
                filename = "YourPDF_Order{}.pdf" #name the PDF


                instance = PackingListDocuments.objects.create() #create a new instance in the model to contain the doc
                instance_key = instance.pk #get the pk of that new model object
                object = PackingListDocuments.objects.get(pk=instance_key) #get that object
                object.Reference_Number = form.cleaned_data.get('Reference_Number')
                object.PackingListDocument.save(filename, File(BytesIO(pdf.content))) #save the document to that object


                messages.success(request, "Success: Packing List Has Been Created!")
                return redirect('HomeView')

    else:
        form = PackingListForm()
        return render(request, 'packlist.html', {'form': form})

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

models.py

class Shipment(models.Model):

    Reference_Number = models.CharField(max_length=100)
    Ultimate_Consignee = models.CharField(max_length=100)

class PackingListDocuments(models.Model):
    Reference_Number = models.ForeignKey(Shipment, null=True, default=None)
    PackingListDocument = models.FileField(upload_to='media')

forms.py

class PackingListForm(forms.ModelForm):
    class Meta:
        model = PackingList
        fields = ['Exporter', 'Consignee', 'Reference_Number', ...]

TRACEBACK

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/create/packing_list

Django Version: 1.11
Python Version: 2.7.10
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'Poseidon',
 'crispy_forms',
 'bootstrap_modal_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/Library/Python/2.7/site-packages/django/utils/deprecation.py" in __call__
  142.             response = self.process_response(request, response)

File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py" in process_response
  58.                             request.session.save()

File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py" in save
  83.         obj = self.create_model_instance(data)

File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py" in create_model_instance
  69.             session_data=self.encode(data),

File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py" in encode
  98.         serialized = self.serializer().dumps(session_dict)

File "/Library/Python/2.7/site-packages/django/core/signing.py" in dumps
  93.         return json.dumps(obj, separators=(',', ':')).encode('latin-1')

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py" in dumps
  250.         sort_keys=sort_keys, **kw).encode(obj)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in encode
  207.         chunks = self.iterencode(o, _one_shot=True)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in iterencode
  270.         return _iterencode(o, 0)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in default
  184.         raise TypeError(repr(o) + " is not JSON serializable")

Exception Type: TypeError at /create/packing_list
Exception Value: <Shipment: 219002> is not JSON serializable

Ответы [ 2 ]

2 голосов
/ 19 марта 2020

Вы храните данные в своем сеансе, и для этого Django необходимо сериализовать данные, прочитайте this . Вы прочтете, что по умолчанию используется сериализатор JSONSerializer.

Теперь form.cleaned_data не обязательно сериализуем для JSON. Любой внешний ключ, представленный как целое число (id), становится фактическим объектом в cleaned_data. Например, form.cleaned_data['Reference_Number'] - это экземпляр Shipment, а не id.

Итак, session['data'] = form.cleaned_data вызывает эту ошибку.

Вам нужно вручную создать словарь, который вы хотите сохранить в сеансе, чтобы обеспечить его сериализацию.

1 голос
/ 19 марта 2020

Хорошо, я давно не работал над Django 1.11, но похоже, что есть некоторое дублирование, и вы можете позволить форме модели сделать больше работы за вас. Я не могу проверить это, но я думаю, что ваше мнение должно быть больше похоже на:

        elif 'save' in request.POST:
            # get a packing list doc from our form but don't save to the db yet
            packing_list_doc = form.save(commit=False)

            context = request.session['data'] = form.cleaned_data  # get the from the form

            pdf = render_to_pdf('packlist_preview.html', context)  # create the PDF

            # what's the point of this? we never use filename...
            filename = "YourPDF_Order{}.pdf"  # name the PDF

            # we already have our packing_list_doc so no need to create one or query one
            # also, the form should have already set the shipment/reference_number on our packing_list_doc

            # for the love of God, please rename PackingListDocument to packing_list_pdf or similar
            # PackingListDocuments.PackingListDocument is not an easy read
            packing_list_doc.PackingListDocument = File(BytesIO(pdf.content))
            packing_list_doc.save()  # because we did commit=False earlier

            messages.success(request, "Success: Packing List Has Been Created!")
            return redirect('HomeView')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...