chrism
chrism

Reputation: 25

Django Rest Framework Creating Foreign Key Serializer context object empty?

I'm trying my hand at creating a little django api for school. At the moment I'm having trouble getting the authorized user when I attempt to create a model with a foreign key. Here is the code I've been trying MODEL:

class JobListing(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
company_name = models.CharField(max_length=80)
job_position = models.CharField(max_length=50)
job_phone = models.CharField(max_length=10)
job_email = models.EmailField()
job_description = models.TextField()
job_schedule = models.CharField(max_length=500)
job_post_date = models.DateField(auto_now_add=True)

VIEW:

class CreatePostView(generics.CreateAPIView):
"""
API endpoint that allows a Job Post to be created
"""
#queryset = ''
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
serializer_class = JobPostingSerializer

SERIALIZER:

class JobPostingSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField()

class Meta:
    model = JobListing
    fields = ('user', 'company_name', 'job_position', 'job_phone', 'job_email', 'job_description', 'job_schedule')

def create(self, validated_data):
    post = super().create(validated_data)
    post.save()
    return post

def get_user(self, instance):
    user = self.context['request'].user
    return user.id

URLS:

    urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth', include('rest_framework.urls', namespace='rest_framework')),
path('home/', views.Home.as_view(), name='home'),
path('login/', views.Login.as_view(), name='login'),
path('getUserDetail/', views.TestSimpleUserJsonAuth.as_view(), name='getUserDetail'),
path('getPosts/', views.getPosts.as_view(), name='getPosts'),
url(r'signup/', views.CreateUserView.as_view(), name='signup'),
url(r'createPost/', views.CreatePostView.as_view(), name='createPost')

I have tried a number of different variations of this including overriding the get context method and trying to change the viewset I'm using. Nothing seems to get it working. Error I'm seeing right now is

IntegrityError at /createPost/ NOT NULL constraint failed: temploybackend_joblisting.user_id

Request Method: POST Request URL: http://192.168.99.100:8000/createPost/

Traceback:

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  303.         return Database.Cursor.execute(self, query, params)

The above exception (NOT NULL constraint failed: temploybackend_joblisting.user_id) was the direct cause of the following exception:

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  494.             response = self.handle_exception(exc)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
  454.             self.raise_uncaught_exception(exc)

File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
  491.             response = handler(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/generics.py" in post
  192.         return self.create(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/rest_framework/mixins.py" in create
  21.         self.perform_create(serializer)

File "/usr/local/lib/python3.6/site-packages/rest_framework/mixins.py" in perform_create
  26.         serializer.save()

File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py" in save
  214.             self.instance = self.create(validated_data)

File "/var/www/temploybackend/serializers.py" in create
  54.       post = super().create(validated_data)

File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py" in create
  917.             instance = ModelClass.objects.create(**validated_data)

File "/usr/local/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py" in create
  417.         obj.save(force_insert=True, using=self.db)

File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py" in save
  729.                        force_update=force_update, update_fields=update_fields)

File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  759.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
  842.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert
  880.                                using=using, raw=raw)

File "/usr/local/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py" in _insert
  1125.         return query.get_compiler(using=using).execute_sql(return_id)

File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1281.                 cursor.execute(sql, params)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  100.             return super().execute(sql, params)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  68.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
  77.         return executor(sql, params, many, context)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "/usr/local/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  89.                 raise dj_exc_value.with_traceback(traceback) from exc_value

File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "/usr/local/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  303.         return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /createPost/
Exception Value: NOT NULL constraint failed: temploybackend_joblisting.user_id

Thank you for any help that can be provided!

Upvotes: 1

Views: 835

Answers (1)

neverwalkaloner
neverwalkaloner

Reputation: 47364

SerializerMethodField is read_only field and not using in object creation. You need to replace it with PrimaryKeyRelatedField with default CurrentUserDefault:

class JobPostingSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(
        read_only=True,  
        default=serializers.CurrentUserDefault()
    )

    class Meta:
        model = JobListing
        fields = ('user', 'company_name', 'job_position', 'job_phone', 'job_email', 'job_description', 'job_schedule')

    def create(self, validated_data):
        post = super().create(validated_data)
        post.save()
        return post

Upvotes: 1

Related Questions