int() argument must be a string or a number, not &

2019-09-01 03:19发布

问题:

I am getting an odd error when uploading a file using the DjangoREST page for a model. Here is the model below

class Documents(models.Model):
    id = models.AutoField(primary_key=True)
    file = models.ForeignKey(Files, related_name="files")
    divider_name = models.TextField(null=True, verbose_name="Divider", blank=True)
    separator = models.TextField(null=True, verbose_name="Separator", blank=True)
    date_changed = models.DateTimeField(auto_now_add=True, verbose_name="Date Changed", blank=True)
    date_document = models.DateTimeField(auto_now_add=True, verbose_name="Document Date", blank=True)
    date_created = models.DateTimeField(auto_now_add=True, auto_now=True, verbose_name="Date Created", blank=True)
    date_filed = models.DateTimeField(auto_now_add=True, auto_now=True, verbose_name="Date Uploaded", blank=True)
    last_viewed = models.DateTimeField(auto_now_add=True, auto_now=True, verbose_name="Last Viewed", blank=True)
    status = models.IntegerField(default=1, verbose_name="Deleted", blank=True)
    sort_order = models.IntegerField(default=1, blank=True)
    description = models.TextField(verbose_name="Document Details", blank=True)
    user_filed = models.IntegerField(verbose_name="Filed By", blank=True)
    user_created = models.IntegerField(verbose_name="Created By", blank=True)
    document_locked = models.IntegerField()
    document_secured = models.IntegerField()
    document_encrypted = models.IntegerField()
    archive_documentid = models.IntegerField()
    extension = models.TextField()
    pages = models.IntegerField()
    file_size = models.IntegerField()
    full_text = models.TextField(null=True, blank=True)
    document_cleaned = models.IntegerField(null=True, blank=True)
    bacth_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
    document_contents = models.TextField(null=True, blank=True)
    process_stepid = models.IntegerField(null=True, blank=True)
    rev_document_id = models.IntegerField(null=True, blank=True)
    document_location = models.FileField(upload_to=settings.MEDIA_ROOT)

    def __unicode__(self):
        return self.id

    class Meta:
        permissions = (('can_view_document', 'Can View Document'),
                       ('can_not_view_document', 'Can Not View Document'),
                       ('can_delete_document', 'Can Delete Document'),
                       ('can_edit_document', 'Can Edit Document'),
                       ('can_export_document', 'Can Export Document'),
                       ('can_move_document', 'Can Move Document'),
                       ('can_add_document', 'Can Add Document'),)
        verbose_name = "Document"
        verbose_name_plural = "Documents"

Here is the serializer

class DocumentSerializer(serializers.ModelSerializer):
    file_id = serializers.PrimaryKeyRelatedField(queryset=Files.objects.all(), many=False)
    class Meta:
        model = Documents
        fields = ('id','file_id', 'divider_name', 'separator', 'date_changed', 'date_document', 'date_created'
                  , 'date_filed', 'last_viewed', 'status', 'sort_order', 'description', 'user_filed', 'user_created'
                  , 'document_locked', 'document_secured', 'document_encrypted', 'archive_documentid', 'extension'
                  , 'pages', 'file_size', 'eform_id', 'full_text', 'document_cleaned', 'bacth_date', 'document_contents'
                  , 'eform_due', 'efrom_complete', 'process_stepid', 'rev_document_id', 'document_location')

and here is the view

class DocumentsViewSet(generics.ListCreateAPIView):
    """
    API endpoint that allows documentss to be viewed or edited.
    """
    queryset = Documents.objects.all()
    serializer_class = DocumentSerializer

So when I hit submit with an attached PNG file it gives me the error.

Request Method: POST
Request URL:    http://localhost:8080/documents/
Django Version: 1.6
Exception Type: TypeError
Exception Value:    
int() argument must be a string or a number, not 'Files'
Exception Location: /usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py in get_prep_value, line 613
Python Executable:  /usr/bin/python
Python Version: 2.7.3

Error Message:

Environment:


Request Method: POST
Request URL: http://localhost:8080/documents/

Django Version: 1.6
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'south',
 'rest_framework',
 'guardian',
 'avatar',
 'django_tables2',
 'serializers',
 'templatetag_handlebars',,
 'main',
 'administration',
 'api')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view
  57.         return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
  399.             response = self.handle_exception(exc)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
  396.             response = handler(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/generics.py" in post
  456.         return self.create(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/mixins.py" in create
  52.             self.object = serializer.save(force_insert=True)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in save
  560.             self.save_object(self.object, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in save_object
  935.         obj.save(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save
  545.                        force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in save_base
  573.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in _save_table
  654.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py" in _do_insert
  687.                                using=using, raw=raw)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py" in _insert
  232.         return insert_query(self.model, objs, fields, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in insert_query
  1511.     return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql
  897.         for sql, params in self.as_sql():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in as_sql
  855.                 for obj in self.query.objs
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py" in get_db_prep_save
  1224.                 connection=connection)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py" in get_db_prep_save
  350.                                       prepared=False)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py" in get_db_prep_value
  606.             value = self.get_prep_value(value)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py" in get_prep_value
  613.         return int(value)

Exception Type: TypeError at /documents/
Exception Value: int() argument must be a string or a number, not 'Files'

回答1:

You have to tell the serializer from which model field do you expect it to get the value from.

class DocumentSerializer(serializers.ModelSerializer):
    file_id = serializers.PrimaryKeyRelatedField(queryset=Files.objects.all(), 
                                                 source='file')

Because if you dont, restframework tries to use the defined name from the serializer so it will use file_id and that is actually not present in the Documents model.

# this is how PrimaryKeyRelatedField resolves its pk value
pk = getattr(obj, self.source or field_name).pk