Django: Unable to Retrieve Phone Number from User's Latest CartOrder in Chatbot View
Problem:
I'm building a chatbot using Django and I'm having trouble getting the phone number from my CartOrder
model. I have a view called log_customer_query
that's supposed to return the phone number of the user's latest order, but it's not working.
Code:
Here's my log_customer_query
view:
def log_customer_query(request):
user = request.user
query_text = request.POST.get('query_text', '')
if not user.is_authenticated:
return JsonResponse({'error': 'User must be authenticated to log a query.'}, status=401)
try:
# Fetch the latest order for the user
latest_order = CartOrder.objects.filter(user=user).latest('order_date')
# Create a new customer query
new_customer = customer.objects.create(
user=user,
title=query_text[:100], # Limit to 100 characters
pid=latest_order.pid,
oid=latest_order.oid,
full_name=latest_order.full_name,
email=latest_order.email,
mobile=latest_order.mobile,
address=latest_order.address,
landmark=latest_order.landmark,
city=latest_order.city,
state=latest_order.state,
postalCode=latest_order.postalCode,
images=latest_order.images,
price=latest_order.price,
old_price=latest_order.old_price,
qty=latest_order.qty,
color=latest_order.color,
size=latest_order.size,
order_date=latest_order.order_date,
return_expire_date=latest_order.return_expire_date,
product_status=latest_order.product_status,
)
return JsonResponse({'success': 'Query logged successfully.'})
except CartOrder.DoesNotExist:
# If the user doesn't have any orders, create a new customer query without order details
new_customer = customer.objects.create(
user=user,
title=query_text[:100], # Limit to 100 characters
)
return JsonResponse({'success': 'Query logged successfully.'})
And here's my CartOrder
model:
class CartOrder(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sku = ShortUUIDField(length=10, max_length=100, prefix="sku", alphabet="1234567890")
pid = ShortUUIDField(null=True, blank=True, default=None)
oid = ShortUUIDField(length=10, max_length=100, prefix="oid", alphabet="1234567890")
full_name = models.CharField(max_length=100, null=True, blank=True)
email = models.CharField(max_length=100, null=True, blank=True)
mobile = models.CharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
landmark = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
coupons = models.ManyToManyField("core.Coupon", blank=True)
state = models.CharField(max_length=100, null=True, blank=True)
postalCode = models.CharField(max_length=100, null=True, blank=True)
title = models.CharField(max_length=100)
images = models.ImageField(upload_to="order-image", default="product.jpg")
price = models.DecimalField(max_digits=10, decimal_places=2, default="0.00")
old_price = models.DecimalField(max_digits=10, decimal_places=2, default="0.00")
qty = models.BigIntegerField(default=0)
color = models.CharField(max_length=500, null=True, blank=True, default=None)
size = models.CharField(max_length=500, null=True, blank=True, default=None)
saved = models.DecimalField(max_digits=10, decimal_places=2, default="0.00")
shipping_method = models.CharField(max_length=100, null=True, blank=True)
tracking_id = models.CharField(max_length=100, null=True, blank=True)
tracking_website = models.CharField(max_length=100, null=True, blank=True)
paid_status = models.BooleanField(default=False)
stripe_payment_intent = models.CharField(max_length=1000, null=True, blank=True)
order_date = models.DateTimeField(auto_now_add=True)
return_expire_date = models.DateField(blank=True, null=True)
product_status = models.CharField(choices=STATUS_CHOICE, max_length=30, default="processing")
return_product = models.BooleanField(default=False)
class Meta:
verbose_name_plural = "Cart Order"
I'm using the following JavaScript code to call the log_customer_query
view:
const chatbotResponses = {
welcome: "{{ response_text|escapejs }}", // This is the welcome message
{% for key, response in responses.items %}
"{{ key }}": "{{ response|escapejs }}",
{% endfor %}
};
const chatOptions = {
welcome: [
{% for option in options %}
{ id: {{ forloop.counter }}, text: "{{ option.text|escapejs }}", response: "{{ option.response_key|escapejs }}" },
{% endfor %}
]
};
// Store options dynamically by parent_key
const optionsByParent = {
{% for parent_key, options_group in options_by_parent.items %}
"{{ parent_key }}": [
{% for option in options_group %}
{ id: {{ forloop.counter }}, text: "{{ option.text|escapejs }}", response: "{{ option.response_key|escapejs }}" },
{% endfor %}
],
{% endfor %}
};
// Function to add a message to the chat log
function addMessageToChatLog(message, type) {
const chatLog = document.getElementById("chat-log");
const messageDiv = document.createElement("div");
messageDiv.classList.add("chat-message");
messageDiv.classList.add(type === "user" ? "user-message" : "bot-message");
messageDiv.textContent = message;
chatLog.appendChild(messageDiv);
// Scroll to the bottom of the chat log
chatLog.scrollTop = chatLog.scrollHeight;
}
// Display chatbot options as buttons
function displayChatOptions(options) {
const chatOptionsContainer = document.getElementById("chat-options");
chatOptionsContainer.innerHTML = ""; // Clear previous options
options.forEach(option => {
const button = document.createElement("button");
button.textContent = option.text;
button.onclick = () => handleOptionClick(option.response, option.text);
chatOptionsContainer.appendChild(button);
});
}
// Handle user clicking on a chatbot option
function handleOptionClick(responseKey, userMessage) {
// Display user's message
addMessageToChatLog(userMessage, "user");
// Check if the responseKey relates to an order and fetch the data accordingly
if (responseKey === "order_status" || responseKey === "shipping_info" || responseKey === "payment_status") {
// Ask for the order ID to provide specific details
askForOrderId(responseKey);
} else {
// Get bot response based on the key
const botResponse = chatbotResponses[responseKey] || "Sorry, I didn’t understand that.";
// Display bot's response
setTimeout(() => {
addMessageToChatLog(botResponse, "bot");
// Check if the bot response is "Sorry, I didn’t understand that."
if (botResponse === "Sorry, I didn’t understand that.") {
// Create a new customer query
createCustomerQuery(userMessage);
} else {
// Show new options if available
if (optionsByParent[responseKey]) {
displayChatOptions(optionsByParent[responseKey]);
}
}
}, 500);
}
}
// Function to prompt the user to input an order ID
function askForOrderId(responseKey) {
const chatOptionsContainer = document.getElementById("chat-options");
chatOptionsContainer.innerHTML = ""; // Clear previous options
const inputField = document.createElement("input");
inputField.type = "text";
inputField.placeholder = "Enter your Order ID";
const submitButton = document.createElement("button");
submitButton.textContent = "Submit";
submitButton.onclick = () => {
const orderId = inputField.value.trim();
if (orderId) {
fetchOrderDetails(orderId, responseKey);
} else {
addMessageToChatLog("Please enter a valid Order ID.", "bot");
}
};
chatOptionsContainer.appendChild(inputField);
chatOptionsContainer.appendChild(submitButton);
}
// Function to fetch order details from the backend
function fetchOrderDetails(orderId, responseKey) {
fetch(`/get_order_info/?order_id=${orderId}&type=${responseKey}`)
.then(response => response.json())
.then(data => {
if (data.error) {
addMessageToChatLog(data.error, "bot");
} else {
// Display relevant order information based on the response key
let orderInfo = "";
if (responseKey === "order_status") {
orderInfo = `Order Status: ${data.status}`;
} else if (responseKey === "shipping_info") {
orderInfo = `Shipping Method: ${data.shipping_method}\nTracking ID: ${data.tracking_id}\nTracking Website: ${data.tracking_website}`;
} else if (responseKey === "payment_status") {
orderInfo = `Payment Status: ${data.payment_status}\nTotal Price: $${data.total_price}`;
}
addMessageToChatLog(orderInfo, "bot");
// Show new options based on the type of request
if (optionsByParent[responseKey]) {
displayChatOptions(optionsByParent[responseKey]);
}
}
})
.catch(error => {
addMessageToChatLog("Sorry, I couldn't fetch the order details. Please try again later.", "bot");
});
}
// Function to create a new customer query
function createCustomerQuery(queryText) {
fetch('/log_customer_query/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
body: JSON.stringify({
query_text: queryText
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
addMessageToChatLog("Your query has been logged. Our support team will get back to you soon.", "bot");
} else {
addMessageToChatLog("Sorry, we couldn't log your query. Please try again later.", "bot");
}
})
.catch(error => {
addMessageToChatLog("Sorry, we couldn't log your query. Please try again later.", "bot");
});
}
// Function to send a message to the chatbot
function sendMessage() {
const userInput = document.getElementById("user-input").value.trim();
if (userInput) {
addMessageToChatLog(userInput, "user");
const responseKey = getResponseKey(userInput);
handleOptionClick(responseKey, userInput);
document.getElementById("user-input").value = "";
}
}
// Function to get the response key based on the user's input
function getResponseKey(userInput) {
// This function should return the response key based on the user's input
// For now, it just returns a default response key
return "default_response";
}
// Display welcome message and options on page load
window.onload = function () {
addMessageToChatLog(chatbotResponses.welcome, "bot"); // Show the welcome message
displayChatOptions(chatOptions.welcome); // Show the initial options
};
Error:
The problem is that the log_customer_query
view is not returning the phone number from the CartOrder
model. I've tried printing out the latest_order
object and the mobile
field, but they're both empty.
Expected Behavior:
I expect the log_customer_query
view to return the phone number of the user's latest order.
Steps to Reproduce:
- Create a new
CartOrder
object with a valid phone number. - Call the
log_customer_query
view using the JavaScript code above. - Check the response from the view to see if it returns the phone number.