0

I have a model Condition that has a field symptoms, which takes multiple different Symptoms objects. Whenever, I make a POST request to create a Condition object, I get the following error:

'Condition: epilepsy' needs to have a value for field "condition" before this many-to-many relationship can be used.

The above 'Condition: epilepsy' is nested between <>, but theres a formatting issue with posting that.

Here is my Condition model:

class Condition(models.Model):
class Treatment():
    SURGERY, NON_INVASIVE, PRESCRIPTION_MEDICINE, NONE = range(4)
    CHOICES = (
        (SURGERY, 'Surgery'),
        (NON_INVASIVE, 'Non-Invasive Treatment'),
        (PRESCRIPTION_MEDICINE, 'Prescription Medicine'),
        (NONE, 'None')
        )
class Medicalfield(models.Model):
    ONCOLOGY, CARDIOLOGY, NEPHROLOGY, PEDIATRICS, ENDOCRONOLOGY, PSYCHOLOGY = range(6)
    CHOICES = (
        (ONCOLOGY, 'Oncology'),
        (CARDIOLOGY, 'Cardiology'),
        (NEPHROLOGY, 'Nephrology'),
        (PEDIATRICS, 'Pediatrics'),
        (ENDOCRONOLOGY, 'Endocronology'),
        (PSYCHOLOGY, 'Psychology')
        )

name = models.CharField(max_length=200)
contagious = models.BooleanField()
treatable = models.BooleanField()
treatment = models.IntegerField(choices=Treatment.CHOICES, null=True)
severeity = models.IntegerField(default=0)
symptoms = models.ManyToManyField('Symptom', blank=True)
medicalfield = models.IntegerField(choices=Medicalfield.CHOICES, null=True)

new = ConditionManager()

def __unicode__(self):
    return u"%s" % ( self.name )

Here is my Serializer

class ConditionSerializer(serializers.ModelSerializer):

def create(self, validated_data):
attrs = validated_data
request = self.context['request']
return Condition.new.create_condition(**attrs)

class Meta:
model = Condition
fields = ('id', 'treatment', 'name', 'contagious', 'treatable', 'treatment', 'severeity', 'symptoms', 'medicalfield')

Here is the Manager

class ConditionManager(models.Manager):
use_in_migrations = True
use_for_related_fields=True

def create_condition(self, *args, **kwargs):
    condition_obj = conditions.models.Condition(name=kwargs['name'], contagious=kwargs['contagious'], treatable=kwargs['treatable'], treatment=kwargs['treatment'], severeity=kwargs['severeity'], symptoms=kwargs['symptoms'], medicalfield=kwargs['medicalfield'])
    condition_obj.save()
    return condition_obj

And here is the View

@api_view(['POST'])
@permission_classes((AllowAny, ))
def create_condition(request):
context = {'request': request}
symptoms = request.data['symptoms']
symptoms = Symptom.objects.filter(name__in=symptoms)
s = []
for symptom in symptoms:
    s.append(symptom.pk)
request.data['symptoms'] = s

serializer = ConditionSerializer(data=request.data, context=context)
if serializer.is_valid():
    serializer.save()
    return response.Response(serializer.data, status=201)
return response.Response(serializer.errors, status=400)

Traceback (most recent call last):

File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 52, in handler
return func(*args, **kwargs)
File "/Users/user/medicalrecords/conditions/views.py", line 28, in create_condition
serializer.save()
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/Users/user/medicalrecords/conditions/serializers.py", line 24, in create
return Condition.new.create_condition(**attrs)
File "/Users/user/medicalrecords/conditions/managers.py", line 17, in create_condition
condition_obj = conditions.models.Condition(name=kwargs['name'], contagious=kwargs['contagious'], treatable=kwargs['treatable'], treatment=kwargs['treatment'], severeity=kwargs['severeity'], symptoms=kwargs['symptoms'], medicalfield=kwargs['medicalfield'])
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 550, in __init__
setattr(self, prop, kwargs[prop])
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 499, in __set__
manager = self.__get__(instance)
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 476, in __get__
return self.related_manager_cls(instance)
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 783, in __init__
(instance, self.source_field_name))
ValueError: "<Condition: epilepsy>" needs to have a value for field "condition" before this many-to-many relationship can be used.
[22/Feb/2017 20:01:45] "POST /conditions/new/condition/ HTTP/1.1" 500 15799

traceback from @snakefcz 's answer

Internal Server Error: /conditions/new/condition/ Traceback (most recent call last): File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py", line 39, in inner response = get_response(request) File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response response = self.process_exception_by_middleware(e, request) File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs) File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 477, in dispatch response = self.handle_exception(exc) File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 437, in handle_exception self.raise_uncaught_exception(exc) File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 474, in dispatch response = handler(request, *args, **kwargs) File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 52, in handler return func(*args, **kwargs) File "/Users/user/medicalrecords/conditions/views.py", line 45, in create_condition return response.Response(serializer.data, status=201) File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 527, in data ret = super(Serializer, self).data File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 262, in data self._data = self.to_representation(self.instance) File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 496, in to_representation ret[field.field_name] = field.to_representation(attribute) File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 643, in to_representation self.child.to_representation(item) for item in iterable File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 479, in to_representation fields = self._readable_fields File "/Library/Python/2.7/site-packages/django/utils/functional.py", line 35, in get res = instance.dict[self.name] = self.func(instance) File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 373, in _readable_fields field for field in self.fields.values() File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 359, in fields for key, value in self.get_fields().items(): File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 1010, in get_fields fields[field_name] = field_class(**field_kwargs) File "/Library/Python/2.7/site-packages/rest_framework/fields.py", line 733, in init super(CharField, self).init(**kwargs) TypeError: init() got an unexpected keyword argument 'view_name'

6
  • You you post the full traceback, please? Commented Feb 22, 2017 at 19:44
  • added the traceback Commented Feb 22, 2017 at 20:02
  • you may need to add null=True for symptom column on your model. Commented Feb 22, 2017 at 20:26
  • where exactly should I put it? in the manager or in the serializer? Commented Feb 22, 2017 at 20:33
  • you have to save the data before saving m2m field data. Commented Feb 23, 2017 at 4:44

2 Answers 2

0

You'll need to create a Symptom serializer in addition to the Condition one. Your ConditionSerializer should look something like:

class ConditionSerializer(serializers.ModelSerializer):
  symptoms = SymptomSerializer(read_only=True, many=True, allow_null=True)
  class Meta:
    model = Condition
    fields = ('id', 'treatment', 'name', 'contagious', 'treatable', 'treatment', 'severeity', 'symptoms', 'medicalfield')

  def create(self, validated_data):
    attrs = validated_data
    request = self.context['request']
    return Condition.new.create_condition(**attrs)
Sign up to request clarification or add additional context in comments.

3 Comments

i just made the change, but now i'm getting an error with the manager:
condition_obj = conditions.models.Condition(name=kwargs['name'], contagious=kwargs['contagious'], treatable=kwargs['treatable'], treatment=kwargs['treatment'], severeity=kwargs['severeity'], symptoms=kwargs['symptoms'], medicalfield=kwargs['medicalfield']) KeyError: 'symptoms'
I edited my answer to show what @Manjit Kumar said. It sounds like you're passing in an empty symptoms when you create your Condition. You should be checking to make sure your kwargs has the key or use the .get() method on it to define a default.
0
## Try it 
@api_view(['POST'])
    @permission_classes((AllowAny, ))
    def create_condition(request):
        context = {'request': request}
        serializer = ConditionSerializer(data=request.data, context=context)
        if serializer.is_valid():
           condition = serializer.save()
           symptoms = request.data['symptoms']
           for symp in symptoms:
               symptom = Symptom.objects.get(id=symp) ## if it's id's you are passing
               condition.symptoms.add(symptom)

           return response.Response(serializer.data, status=201)
    return response.Response(serializer.errors, status=400)

1 Comment

It's successfully creating the object, but its giving me a 500 error. I edited the question with the traceback

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.