X-Frame-Options

I could literally scream

No, seriously, I could. I swear to God of I see this error message one more time I’m going to lose it.

I am literally on the end of my tether with this thing, my patience with this thing is going to seriously snap at any second.

Why do I constantly return the error message:

  File "C:\Users\xxx\OneDrive - xxx \xxx\.venv\Lib\site-packages\django\middleware\clickjacking.py", line 27, in process_response       
    if response.get("X-Frame-Options") is not None:
       ^^^^^^^^^^^^
AttributeError: 'SafeString' object has no attribute 'get'

What middle ware do I need here?

For your information, this is my Django Middleware setup?

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    "whitenoise.middleware.WhiteNoiseMiddleware",
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Is your view actually returning an HTTP response object? It appears based on the error that you’re trying to return a string, which won’t work.

Would you consider posting your code? Otherwise, we can but speculate and your screaming will be as useful as our responses.

Yes, this my code:

from django.shortcuts import render
import requests, json, logging
from blauwestadtech import utils
from blauwestadtech.logging_config import logging_configuration

# Call configuration function
logging_configuration()

# Create logger instance
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) 
logger.info("Logger in "+__name__+" is initialised...")

# Create your views here.
def create_and_submit_ticket(request):
  
  '''The create_and_submit_ticket view is designed to streamline the process of submitting support tickets. It accepts essential parameters for a ticket and processes them to generate structured ticket data.
    This is then converted into a JSON format sent to the Freshdesk.
    Please ensure you have a subscription level which allows you to obtain your API hey

    :return ticket_data: A dictionary containing all the submitted ticket information.
    
  '''
  from . import freshdesk_api_key as fd
  from legal.forms import LegalDocumentsFeedback
  from django.shortcuts import redirect
  from django.shortcuts import HttpResponseRedirect
  import os
  from django.conf import settings

  API_KEY = fd.FRESHDESK_API_KEY
  API_URL = fd.MY_FRESHDESK_API_URL

  logger.info("Testing..")
  
  if request.method == 'POST':
    logger.info("Method Status:POST")
    form = LegalDocumentsFeedback(request.POST, request.FILES)
    if form.is_valid():
      name        = form.cleaned_data['name']
      subject     = form.cleaned_data['subject']
      description = form.cleaned_data['description']
      email       = form.cleaned_data['email']
      attachments = request.FILES.getlist('attachments') 
  
    ticket_data = {
        "name": name,
        "subject": subject,
        "description": description,
        "email": email,
        'priority' : 1,
        'status' : 2,
        'group_id': 201000039106,
        'responder_id': 201002411183  
    }

    files = []
    ALLOWED_EXTENSIONS = [".pdf", ".jpeg", ".png"]

    if attachments:
      try:
        for attachment in attachments:
          extension = os.path.splitext(attachment.name)[1].lower()
          if extension in ALLOWED_EXTENSIONS:
            logger.info(f"Adding file {attachment} to list...")
            files.append(('attachments[]', (attachment.name, attachment, attachment.content_type)))
            logger.info(f"Attachment added {attachment}")
          else:
            logger.warning(f"ATTACMENTS => Invalid file type: {extension}")

      except Exception as e:
        logger.exception("ATTACHMENTS => Error in uploading attachments. This was caused by: %s",e)

    else:
          logger.info("No attachments were uploaded")
    
    API_KEY = fd.FRESHDESK_API_KEY
    API_URL = fd.MY_FRESHDESK_API_URL
    
    try:
      create_ticket = requests.post(
        API_URL,
        auth    = (API_KEY, 'X'),
        data    = ticket_data,
        files   = files,
        timeout = 30,
        headers = {'Content-Type' : 'application/json'}
      )

      logger.debug("Response Status Code: %s ", create_ticket.status_code)
      logger.debug("Response Content: %s ", create_ticket.json())

      if create_ticket.status_code == 201:
          return redirect('successful_submission')
      else:
          return redirect('raise_support_ticket_error')
      
    except requests.RequestException as req_ex:
        # Handle errors from the requests library
        logger.exception("Request failed with exception: %s", req_ex)
        print("exception")
        return redirect('raise_support_ticket_error')
        
    except Exception as e:
        # Handle other exceptions
        logger.exception("An unexpected error occurred: %s", e)
        print("exception")
        return redirect('raise_support_ticket_error')

  else:
    form = LegalDocumentsFeedback()

  return form

This is called by the URL name in the urls.py

from django.urls import path
from django.shortcuts import render
from . import views

urlpatterns = [
    path('raise-support-ticket/', views.successful_submission, name="successful_submission"),
    path('raise-support-ticket-error/', views.submission_error, name='raise_support_ticket_error'),
    path('raise_ticket/', views.create_and_submit_ticket, name='raise_support_ticket'),
]

Error logs

2024-08-12 10:16:44,611 - support.views - DEBUG - Response Status Code: 400
2024-08-12 10:16:44,612 - support.views - DEBUG - Response Content: {'code': 'invalid_json', 'message': 'Request body has invalid json format'}

The next time I see the same error message, I will pick this computer up and I will throw it against the wall

It’s not returning an HTTP response, its returning a 500 error. I’m getting so tired of seeing that message.

It’s not easy to help when you’re this frustrated. Go take a walk around the block, come back with a clearer head, and then try making a cut-down version of your app that still has the same problem.

  • Its not easy seeing the same error message over and over and over again when you try EVERYTING,
  • it’s not easy dealing with 30 years worth of anger issues stemming from childhood trauma when you have been made to feel worthless and inadequate and ignored, and now I have Python ignoring me when I have specifically tell it so submit form data to my CRM,
  • its not easy trying to keep calm when I all I want to do is scream,
  • its not easy being SICK to the back teeth of seeing error after error after error,
  • its not easy when it even gives you the error (thanks to logging), you fix the error and you get another error, its just a moaning little child where nothing is good enough.

However, upon further improvements to logging, it return this absolutely ridiculous:

2024-08-12 10:16:44,611 - support.views - DEBUG - Response Status Code: 400
2024-08-12 10:16:44,612 - support.views - DEBUG - Response Content: {'code': 'invalid_json', 'message': 'Request body has invalid json format'}

Why it it telling me its an invalid JSON format when it’s not?

Code updated.

  return form

^-- this is returning a LegalDocumentsFeedback object. It needs to return an HttpResponse object. Since you’ve imported render in this file, probably you want to call render() with a template name and a context dictionary containing your form, and return the result of that.

Now solved.

You need to handle the post requests differently depending on whether you submit your form with attachments or not, no thanks for Freshdesk for pointing me in the first direction due to the fact that they’re essentially minimum-wage incompetents who tell their customer that it’s “outside of their scope” when they have no idea what the solution to the problem is.

This is the correct setup. Thank everyone for your time.

from django.shortcuts import render
import requests, json, logging
from django.contrib import messages
from blauwestadtech import utils
from blauwestadtech.logging_config import logging_configuration

# Call configuration function
logging_configuration()

# Create logger instance
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) 
logger.info("Logger in "+__name__+" is initialised...")

# Create your views here.
def create_and_submit_ticket(request):
  
  '''The create_and_submit_ticket view is designed to streamline the process of submitting support tickets. It accepts essential parameters for a ticket and processes them to generate structured ticket data.
    This is then converted into a JSON format sent to the Freshdesk.
    Please ensure you have a subscription level which allows you to obtain your API hey

    :return ticket_data: A dictionary containing all the submitted ticket information.
    
  '''
  from . import freshdesk_api_key as fd
  from legal.forms import LegalDocumentsFeedback
  from django.shortcuts import redirect
  from django.shortcuts import HttpResponseRedirect
  import os
  from django.conf import settings

  API_KEY = fd.FRESHDESK_API_KEY
  API_URL = fd.MY_FRESHDESK_API_URL

  logger.info("Testing..")
  
  if request.method == 'POST':
    logger.info("Method Status:POST")
    form = LegalDocumentsFeedback(request.POST, request.FILES)
    if form.is_valid():
      name        = form.cleaned_data['name']
      subject     = form.cleaned_data['subject']
      description = form.cleaned_data['description']
      email       = form.cleaned_data['email']
      attachments = request.FILES.getlist('attachments') 
  
    ticket_data = {
        "name": name,
        "subject": subject,
        "description": description,
        "email": email,
        'priority' : 1,
        'status' : 2,
        'group_id': 201000039106,
        'responder_id': 201002411183  
    }

    files = []
    ALLOWED_EXTENSIONS = [".pdf", ".jpeg", ".png", ".jpg"]

    if attachments:
      unsupported_files = set()
      try:
        for attachment in attachments:
          extension = os.path.splitext(attachment.name)[1].lower()
          if extension in ALLOWED_EXTENSIONS:
            logger.info(f"Adding file {attachment} to list...")
            files.append(('attachments[]', (attachment.name, attachment, attachment.content_type)))
            logger.info(f"Attachment added {attachment}")
          else:
            if extension not in unsupported_files:
              logger.warning(f"ATTACMENTS => Invalid file type: {extension}")
              allowed_extensions_str = ", ".join(ALLOWED_EXTENSIONS)
              error_message = f"Unsupported file type: {extension}. We only accept: {allowed_extensions_str}."
              messages.error(request, error_message)
              unsupported_files.add(extension)
      except Exception as e:
        logger.exception("ATTACHMENTS => Error in uploading attachments. This was caused by: %s",e)
        messages.error(request, "Error uploading attachments. Please try again.")

      try:
        logger.info("Attachments were uploaded, now attampting API request...")
        create_ticket = requests.post(
          API_URL,
          auth    = (API_KEY, 'X'),
          data    = ticket_data,
          files   = files,
          timeout = 30,
        )

      except requests.RequestException as req_ex:
          # Handle errors from the requests library
          logger.exception("Request failed with exception: %s", req_ex)
          return redirect('raise_support_ticket_error')

      except Exception as e:
          # Handle other exceptions
          logger.exception("An unexpected error occurred: %s", e)
          return redirect('raise_support_ticket_error')
      
    else:
      logger.info("No attachments were uploaded, now attampting API request....")
      try:
        create_ticket = requests.post(
          API_URL,
          auth    = (API_KEY, 'X'),
          json    = ticket_data,
          timeout = 30,
          headers = {'Content-Type' : 'application/json'}
          
        )

      except requests.RequestException as req_ex:
          # Handle errors from the requests library
          logger.exception("Request failed with exception: %s", req_ex)
          return redirect('raise_support_ticket_error')

      except Exception as e:
          # Handle other exceptions
          logger.exception("An unexpected error occurred: %s", e)
          return redirect('raise_support_ticket_error')
 
    logger.debug("Response Status Code: %s ", create_ticket.status_code)
    logger.debug("Response Content: %s ", create_ticket.json())

    status_code = create_ticket.status_code
    status_code_str = str(status_code)
    status_for_for_error_message = f"Error Code {status_code_str}"
    messages.error(request,status_for_for_error_message)

    if create_ticket.status_code == 201:
        return redirect('successful_submission')
    else:
        return redirect('raise_support_ticket_error')

  else:
    form = LegalDocumentsFeedback()

  return form