You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中POST请求contact_number字段JSON格式错误排查求助

Let's break down the issue and fix it step by step:

1. Why the Format Error Happens

a. Incorrect Request Payload (Postman Side)

Your invalid Postman request wraps a stringified array inside another array:

{ 
  "name": "3123", 
  "email": "qwe@gmail.com", 
  "address": "Col", 
  "note": "noting", 
  "contact_number": [ "['3123', '123123']" ] 
}

Here, contact_number contains a single string value ("['3123', '123123']") instead of an array of plain phone number strings. The Admin page works because it correctly sends a flat array of strings, just like your valid example shows.

b. Backend Code Bug (Django View)

Even if you send the correct payload, your current views.py code will still fail. You're passing the entire contact_number array directly to ContactNumber.objects.create(), but your ContactNumber model expects a single string for the contact_number field. Each phone number needs its own separate ContactNumber instance linked to the parent PhoneBook entry.

2. Fixes to Resolve the Issue

Step 1: Correct the Postman Request Payload

Make sure your Postman POST body uses the same format as the Admin page: send a flat array of phone number strings for contact_number. No nested strings or extra quotes around the array elements.

Step 2: Fix the Django View Code

Update your phonebook_list POST handler to loop through each contact number and create individual ContactNumber entries. We'll also add proper validation to catch invalid payloads early:

@method_decorator(csrf_exempt)
def phonebook_list(request):
    if request.method == 'GET':
        phonebooklist = PhoneBook.objects.all()
        serialized_data = [pb.to_json() for pb in phonebooklist]
        return JsonResponse(serialized_data, safe=False)
    elif request.method == 'POST':
        try:
            # Parse and validate the request JSON
            data = json.loads(request.body.decode('utf8'))
            
            # Check for required fields
            required_fields = ['name', 'address', 'email', 'note', 'contact_number']
            for field in required_fields:
                if field not in data:
                    return JsonResponse({"error": f"Missing required field: {field}"}, status=400)
            
            # Ensure contact_number is an array of strings
            if not isinstance(data["contact_number"], list):
                return JsonResponse({"error": "contact_number must be an array of phone number strings"}, status=400)
            for num in data["contact_number"]:
                if not isinstance(num, str):
                    return JsonResponse({"error": f"Invalid phone number: {num} must be a string"}, status=400)
            
            # Create the main PhoneBook entry
            new_contact = PhoneBook.objects.create(
                name=data["name"],
                address=data["address"],
                email=data["email"],
                note=data["note"]
            )
            
            # Create a ContactNumber record for each phone number
            for number in data["contact_number"]:
                ContactNumber.objects.create(
                    contact_number=number,
                    number=new_contact  # Note: This ForeignKey name is confusing, see optional step below
                )
            
            # Return the successfully created contact data
            return JsonResponse({"created": new_contact.to_json()}, safe=False)
        
        except json.JSONDecodeError:
            return JsonResponse({"error": "Invalid JSON payload"}, status=400)
        except Exception as e:
            return JsonResponse({"error": f"Server error: {str(e)}"}, status=500)

Step 3: Optional - Improve Model Naming (For Clarity)

Your ContactNumber model's ForeignKey field is named number, which is misleading since it links to a PhoneBook instance. Renaming it will make your code easier to read and maintain:

class ContactNumber(models.Model):
    phone_book = models.ForeignKey(PhoneBook, related_name="contact_numbers")
    contact_number = models.CharField(max_length=30)
    
    def __str__(self):
        return self.contact_number

If you make this change, update the view code where you create ContactNumber instances to use phone_book=new_contact instead of number=new_contact.

3. Why the Admin Page Works

The Django Admin automatically handles the one-to-many relationship between PhoneBook and ContactNumber correctly. It lets you add multiple contact numbers as separate entries, which translates to creating individual ContactNumber records linked to the same PhoneBook instance. When fetching data, it also serializes these entries into a flat array, matching the output of your to_json() method.

内容的提问来源于stack exchange,提问作者bossajie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:17:54