2

My models.py has 3 fields. One of them is JSONField()

attribute = JSONField(null=True, blank=True)  # Free to add any note to here
type = models.CharField(max_length=30, choices=FileType.choices, default=FileType.zipcode)
file = models.FileField(upload_to='import_files')

I normally set JSONField(null=True, blank=True) for the sake of easiness.

def test_upload_and_process_data_complete_case(self):
    from soken_web.apps.imported_files.models import ImportFile
    with open(str(settings.BASE_DIR) + '/apps/zipcodes/complete.xlsx', 'rb') as uploaded_file:
        data = {
            'attribute': {'author': 'Singh'},
            'type': ImportFile.FileType.zipcode,
            'file': uploaded_file
        }
        response = self.client.post(reverse('api:import_file-list'), data, format='multipart')
        response.render()

        self.assertEqual(status.HTTP_201_CREATED, response.status_code)

And my test runs fine without shooting with JSONField

Experiment:
When I shoot with JSONField like the given. It will failed with this error

AssertionError: Test data contained a dictionary value for key 'attribute', but multipart uploads do not support nested data. You may want to consider using format='json' in this test case.

However, from my understanding I have to post with multipart because of file.

Question:
Is it possible to do unittest shoot the endpoint that has JSONField and FileField in the same time?

Reference:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 14: invalid start byte

4
  • can you just decode the file to a string and then send the object as format=json? What's in the file? Commented Sep 29, 2017 at 15:27
  • is right parser being used ass discused here stackoverflow.com/questions/36881771/… ? Commented Sep 29, 2017 at 15:57
  • @SamRedway I have never do that. Thanks for your response. This supposed to be ancient question, but I could not find the solution. Commented Sep 30, 2017 at 8:28
  • @andi Let me take time read and digest it for a big moment. Commented Sep 30, 2017 at 8:32

1 Answer 1

4

After played around with parser.
I found that nothing in the configurations are wrong. Only one thing I missed is. I have to put single quote cover the {"author": "Singh"}.
Because web browser does submit in the str not python object.

def test_upload_and_process_data_complete_case(self):
    from soken_web.apps.imported_files.models import ImportFile
    with open(str(settings.BASE_DIR) + '/apps/zipcodes/complete.xlsx', 'rb') as uploaded_file:
        data = {
            'attribute': '{"author": "Singh"}',
            'type': ImportFile.FileType.zipcode,
            'file': uploaded_file
        }
        response = self.client.post(reverse('api:import_file-list'), data, format='multipart')
        response.render()

        self.assertEqual(status.HTTP_201_CREATED, response.status_code)
Sign up to request clarification or add additional context in comments.

1 Comment

Also worth noting that you'll explicitly need single quotes around it ('{"verbosity": "default"}' will work, and "{'verbosity': 'default', }" will not (will throw something like it wants valid JSON, and single quotes are not allowed in JSON).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.