0

I have a django project built using custom django admin and django forms. I'm trying to make a post request to an API. How do i get the data from the forms in a nested format.

My forms currently looks like this,

class CampaignForm(forms.Form):
    consumer = forms.CharField(max_length=200)
    startDate = forms.DateTimeField(
        input_formats=['%d/%m/%Y %H:%M'])
    endDate = forms.DateTimeField(
        input_formats=['%d/%m/%Y %H:%M'])
    referreeCredits = forms.IntegerField()
    referrerCredits = forms.IntegerField()
    maxReferreeCredits = forms.IntegerField()
    maxReferrerCredits = forms.IntegerField()
    message = forms.CharField(max_length=200)
    kramerTemplateId = forms.CharField(max_length=200)
    paymentMode = forms.CharField(max_length=200)
    eventName = forms.CharField(max_length=200)
    operator = forms.CharField(max_length=200)
    value = forms.IntegerField()
    mOperator = forms.CharField(max_length=200)
    mValue = forms.IntegerField()
    mReferrerCredits = forms.IntegerField()

The json that the API takes looks like this:

{
  "consumer": "FILING",
  "startDate": 0,
  "endDate": 0,
  "referreeCredits": 0,
  "referrerCredits": 0,
  "maxReferreeCredits": 0,
  "maxReferrerCredits": 0,
  "message": "string",
  "kramerTemplateId": "string",
  "eventRules": [
    {
      "eventName": "string",
      "operator": "EQUAL",
      "value": 0
    }
  ],
  "milestoneRules": [
    {
      "operator": "EQUAL",
      "value": 0,
      "referrerCredits": 0
    }
  ],
  "paymentMode": "PAYTM"
}

I've also tried hardcoding the json unsuccessfully(I'm getting a 400 bad request error),

def campaign_add(self, request):
        form = CampaignForm()
        if request.method == 'POST':
            import ipdb; ipdb.set_trace()
            form = CampaignForm(request.POST)
            if form.is_valid():
                dat = {
                        "consumer": request.POST["consumer"],
                        "startDate": self.datetime_to_epoch(request.POST["startDate"]),
                        "endDate": self.datetime_to_epoch(request.POST["endDate"]),
                        "referreeCredits": int(request.POST["referreeCredits"]),
                        "referrerCredits": int(request.POST["referrerCredits"]),
                        "maxReferreeCredits": int(request.POST["maxReferreeCredits"]),
                        "maxReferrerCredits": int(request.POST["maxReferrerCredits"]),
                        "message": request.POST["message"],
                        "kramerTemplateId": request.POST["kramerTemplateId"],
                        "eventRules": [
                            {
                            "eventName": request.POST["eventName"],
                            "operator": request.POST["operator"],
                            "value": int(request.POST["value"])
                            }
                        ],
                        "milestoneRules": [
                            {
                            "operator": request.POST["mOperator"],
                            "value": int(request.POST["mValue"]),
                            "referrerCredits": int(request.POST["mReferrerCredits"])
                            }
                        ],
                        "paymentMode": request.POST["paymentMode"]
                    }

                # import ipdb; ipdb.set_trace()
                res = requests.post("https://example.com/", data=dat)
                if res.status_code == 201 or res.status_code == 200:
                    messages.success(request, 'Success!')
                    return redirect("admin:campaign-pg1")
                else:
                    messages.error(request, 'Submission Failed.')
        return TemplateResponse(request, "admin/campaign_add.html", {"form":form})

How do I make a post request in the above mentioned format?

2
  • Note, you should be getting the data from the form.cleaned_data dict, not directly from request.POST. Apart from anything else, this will have already converted integers where necessary. Commented Apr 3, 2019 at 10:29
  • I made the appropriate changes in my code. Thanks! Commented Apr 3, 2019 at 10:32

1 Answer 1

3

By default, if you use data=dat in the requests library, the data is posted as form data, not as JSON. You should do this:

 res = requests.post("https://example.com", json=dat)

which will automatically set the Content-Type header correctly to application/json, or:

 res = request.post("https://example.com", data=json.dumps(dat), headers={'content-type': 'application/json'})
Sign up to request clarification or add additional context in comments.

Comments

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.