I'm trying to add data to the POS's order and send that data to the 'pos.order' model based on the site https://odoo-development.readthedocs.io/en/latest/dev/pos/load-data-to-pos.html. To make my case more generic I'm creating a new odoo model named 'custom.model', I'm creating a relation with the 'pos.config' to help me with the model domain in javascritp latter with the following code:
# -*- coding: utf-8 -*-
from odoo import models, fields
class custom_model(models.Model):
_name = 'custom.model'
name = fields.Char(string='name')
class myPosConfig(models.Model):
_inherit = 'pos.config'
custom_model_id = fields.Many2one('custom.model', string='My custom model')
Then I add the relation of my interest in the 'pos.order' model with the following python code:
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class myPosOrder(models.Model):
_inherit = 'pos.order'
custom_model_id = fields.Many2one('custom.model', string='My model')
Then I add my custom model in the frontend with a javascript file with the following code:
odoo.define('kyohei_pos_computerized_billing.billing_dosage', function (require) {
"use strict";
var models = require('point_of_sale.models');
var _super_order_model = models.Order.prototype;
models.load_models([{
model: 'custom.model',
label: 'custom_model',
fields: ['name'],
// Domain to recover the custom.model record related to my pos.config
domain: function(self){ return [['id', '=', self.config.custom_model_id[0]]];},
loaded: function(self, dosage){self.dosage = dosage[0]},
}]);
});
Then I add the following code to the same javascript file, so the record is stored in the browser and when needed to send the data to the backend:
models.Order = models.Order.extend({
initialize: function(){
_super_order_model.initialize.apply(this,arguments);
if (this.custom_model){
this.custom_model = this.pos.custom_model;
}
},
export_as_JSON: function () {
var data = _super_order_model.export_as_JSON.apply(this, arguments);
data.custom_model = this.custom_model;
return data
},
init_from_JSON: function (json) {
this.custom_model = json.custom_model;
_super_order_model.init_from_JSON.call(this. json);
},
export_for_printing: function() {
var json = _super_order_model.export_for_printing.apply(this,arguments);
json.custom_model = this.custom_model;
return json;
},
});
and finally added the following method to the 'pos.order' model so it stores what the frontend sends:
#api.model
def _order_fields(self, ui_order):
fields = super(MyPosOrder, self)._order_fields(ui_order)
fields.update({
'custom_model': ui_order('custom_model.id')
})
return fields
But the field still isn't being filled with my custom_model's registry id, and I get the following error:
Odoo Server Error
Traceback (most recent call last):
File "/opt/odoo/odoo13/odoo/http.py", line 619, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/opt/odoo/odoo13/odoo/http.py", line 309, in _handle_exception
raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])
File "/opt/odoo/odoo13/odoo/tools/pycompat.py", line 14, in reraise
raise value
File "/opt/odoo/odoo13/odoo/http.py", line 664, in dispatch
result = self._call_function(**self.params)
File "/opt/odoo/odoo13/odoo/http.py", line 345, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/opt/odoo/odoo13/odoo/service/model.py", line 93, in wrapper
return f(dbname, *args, **kwargs)
File "/opt/odoo/odoo13/odoo/http.py", line 338, in checked_call
result = self.endpoint(*a, **kw)
File "/opt/odoo/odoo13/odoo/http.py", line 910, in __call__
return self.method(*args, **kw)
File "/opt/odoo/odoo13/odoo/http.py", line 510, in response_wrap
response = f(*args, **kw)
File "/opt/odoo/odoo13/addons/web/controllers/main.py", line 1320, in call_kw
return self._call_kw(model, method, args, kwargs)
File "/opt/odoo/odoo13/addons/web/controllers/main.py", line 1312, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/opt/odoo/odoo13/odoo/api.py", line 383, in call_kw
result = _call_kw_model(method, model, args, kwargs)
File "/opt/odoo/odoo13/odoo/api.py", line 356, in _call_kw_model
result = method(recs, *args, **kwargs)
File "/opt/odoo/odoo13/addons/point_of_sale/models/pos_order.py", line 440, in create_from_ui
order_ids.append(self._process_order(order, draft, existing_order))
File "/opt/odoo/odoo13/addons/point_of_sale/models/pos_order.py", line 122, in _process_order
pos_order = self.create(self._order_fields(order))
File "/opt/odoo/odoo13/kyohei_addons/kyohei_pos_computerized_billing/models/pos_order.py", line 27, in _order_fields
'test_string': ui_order('dosage.id'),
TypeError: 'dict' object is not callable
This error due to of the argument mismatch on the method, just check on the odoo-13 this method _process_order
In your code, you were using the older version method and from the odoo13 version, it is changed.
You have to update the field in this method, where the data came from the export_as_JSON function.
#api.model
def _order_fields(self, ui_order):
pos_order = super(KyoheiComputerizedPosOrder, self)._order_fields(ui_order)
# Get the data from ui_order
return pos_order
Thanks
I want to thank #Dipen Shah, finally got the code working. The python file should look like the following:
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class MyPosOrder(models.Model):
_inherit = 'pos.order'
test_string = fields.Char(string='test_string')
#api.model
def _order_fields(self, ui_order):
order_fields = super(MyPosOrder, self)._order_fields(ui_order)
order_fields['test_string'] = ui_order.get('test_string')
return order_fields
The file that could help to understand this issue is the pos_restaurant's pos_order.py
Related
I am working on channels using django, and i am having 2 different consumers for 2 differrent web pages , but while executing the web page i am getting type error for consumer
This is consumer.py file
from channels.consumer import AsyncConsumer
import asyncio
class ChatConsumer(AsyncConsumer):
async def websocket_connect(self,event):
await self.send(
{
'type':'websocket.accept',
}
)
print("connected",event)
async def websocket_receive(self,event):
print("received",event)
async def websocket_disconnect(self,event):
print("disconnected",event)
class HomeConsumer(AsyncConsumer):
async def websocket_connect(self,event):
await self.send(
{
'type':'websocket.accept',
}
)
print("connected",event)
async def websocket_receive(self,event):
print("received",event)
async def websocket_disconnect(self,event):
print("disconnected",event)
This is my routing.py file
import os
from channels.routing import ProtocolTypeRouter,URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
from django.urls import re_path
from .consumer import ChatConsumer,HomeConsumer
from django.conf.urls import url
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
url(r"^profile/(?P<username>[\w.#+-]+)",ChatConsumer),
url("profile",HomeConsumer)
]
)
)
)
})
THis is my websocket javascript:
var loc = window.location
console.log(loc)
var endpoint = "ws://" + loc.host + loc.pathname
var socket = new WebSocket(endpoint)
socket.onmessage = function(e) {
console.log("message", e)
}
socket.onopen = function(e) {
console.log("open", e)
}
socket.onclose = function(e) {
console.log("close", e)
}
socket.onerror = function(e) {
console.log("error", e)
}
This is my urls.py file:
from django.contrib import admin
from django.urls import path,include
from connectedfour.views import home,game,profile
urlpatterns = [
path('admin/', admin.site.urls),
path('',home,name='home'),
path('profile',profile,name='profile'),
path('accounts/',include('accounts.urls')),
path('profile/<username>',game,name='game')
]
I am getting error like this:
HTTP GET /profile 200 [0.03, 127.0.0.1:50706]
WebSocket HANDSHAKING /profile [127.0.0.1:50708]
Exception inside application: HomeConsumer() takes no arguments
Traceback (most recent call last):
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__
return await self.application(scope, receive, send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__
return await application(scope, receive, send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/security/websocket.py", line 37, in __call__
return await self.application(scope, send, receive)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/sessions.py", line 254, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/auth.py", line 181, in __call__
return await super().__call__(scope, receive, send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/middleware.py", line 26, in __call__
return await self.inner(scope, receive, send)
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/channels/routing.py", line 150, in __call__
return await application(
File "/home/rusker/Desktop/Pydjango/tenv/lib/python3.8/site-packages/asgiref/compatibility.py", line 33, in new_application
instance = application(scope)
TypeError: HomeConsumer() takes no arguments
WebSocket DISCONNECT /profile [127.0.0.1:50708]
Try putting round brackets at the view argument to specify a class with no argument e.g. url("profile",HomeConsumer())
You should remove AsyncConsumer from the HomeConsumer class.
i think in recent channels version you should write the url pattern like so.
url("profile", HomeConsumer.as_asgi())
just as you have your ".as_view()" when writing url patterns for normal class based view, because the HomeConsumer is also like a class based view.
i fixed the issue by using the Asgi.py, its almost same setup of routing.py but with slight change,
i refered to the article :
https://channels.readthedocs.io/en/stable/installation.html
(i used Django2.2 version of code)
also its important you make your Asgi Handler like this:
application = ProtocolTypeRouter({
"http": AsgiHandler(),
'websocket': AuthMiddlewareStack(
URLRouter(
[
url(r"^auction/(?P<room_name>[-\w]+)$", AuctionConsumer.as_asgi()),
]
)
)
})
i wish this will help anyone because i struggled for long time until i found the solution.
For example, here is some lines of code in my JS code embedded in the HTML file:
document.getElementById("enter").onclick = e => {
e.preventDefault();
var field1 = document.getElementById("field1").value;
var field2 = document.getElementById("field2").value;
var localStorageField = localStorage.getItem("field3");
window.location.href = "{{ url_for("content", ???) }}"
\\ or something else? I think this line would most likely not work, because the url_for is filled in when the page is loaded, rather than when it is called.
}
How do I make the page get redirected to the content() function, where it receives field1, field2 and localStorageField as arguments?
Edit: When I used Tobin's answer, an error occurs:
Traceback (most recent call last):
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask_socketio/__init__.py", line 46, in __call__
start_response)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/engineio/middleware.py", line 74, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/scythia/Desktop/Flask_LocalStorage/venv/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
TypeError: content() missing 3 required positional arguments: 'field1', 'field2' and 'local'
flask function:
app = Flask(__name__)
app.secret_key = os.getenv("SECRET_KEY")
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_PERMANENT'] = False
jsg = JSGlue(app)
#app.route("/")
def content(field1,field2,local):
return render_template("index.html", field1 = field1, field2 = field2, local = local)
I suggest you use Flask-JSGlue: it allows you to properly connect your Flask application to the front end.
INSTALLATION:
$ pip install Flask-JSGlue
USAGE:
Back-end:
from flask import Flask
from flask_jsglue import JSGlue
app = Flask(__name__)
jsglue = JSGlue(app)
Front-end:
In <head>
{{ JSGlue.include() }}
In your JS code:
document.getElementById("enter").onclick = e => {
e.preventDefault();
var field1 = document.getElementById("field1").value;
var field2 = document.getElementById("field2").value;
var localStorageField = localStorage.getItem("field3");
location.href = Flask.url_for("content", {param1: field1, param2: field2, param3: localStorageField});
}
FLASK ROUTE:
from flask import request
#app.route('/', methods=['GET', 'POST'])
def content():
field1 = request.args.get('param1')
field2 = request.args.get('param2')
local = request.args.get('param3')
return render_template("index.html", field1=field1, field2=field2, local=local)
im very new to Javascript, Django & web development in general. Im following a cs50 web dev course by harvard and I have to design a front-end for an email client that makes API calls to send and receive emails.
Ill get mail, send mail, and update emails by using an API that is written specifically for us.
I need to send a GET request to /emails/ where is either inbox, sent, or archive, and it will return back (in JSON form) a list of all emails in that mailbox, in reverse chronological order.
How to fetch, as instructed by the course:
fetch('/emails/sent')
.then(response => response.json())
.then(emails => {
// Print emails
console.log(emails);
// ... do something else with emails ...
});
I put this exact code in my .js file and it gives me these two errors:
GET http://127.0.0.1:8000/emails/sent 500 (Internal Server Error)
load_mailbox # inbox.js:85
(anonymous) # inbox.js:24
127.0.0.1/:1 Uncaught (in promise) SyntaxError: Unexpected token < in
JSON at position 0
Promise.then (async)
load_mailbox # inbox.js:87
(anonymous) # inbox.js:6
What shows at the cmd:
Is the issue at the timestamp of the model in django? I dont understand why.
Internal Server Error: /emails/sent
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python\Python38\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\AG\Desktop\cs50\mail\mail\views.py", line 96, in mailbox
return JsonResponse([email.serialize() for email in emails], safe=False)
File "C:\Users\AG\Desktop\cs50\mail\mail\views.py", line 96, in <listcomp>
return JsonResponse([email.serialize() for email in emails], safe=False)
File "C:\Users\AG\Desktop\cs50\mail\mail\models.py", line 26, in serialize
"timestamp": self.timestamp.strftime("%b %-d %Y, %-I:%M %p"),
ValueError: Invalid format string
Code given by the course:
models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Email(models.Model):
user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="emails")
sender = models.ForeignKey("User", on_delete=models.PROTECT, related_name="emails_sent")
recipients = models.ManyToManyField("User", related_name="emails_received")
subject = models.CharField(max_length=255)
body = models.TextField(blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
read = models.BooleanField(default=False)
archived = models.BooleanField(default=False)
def serialize(self):
return {
"id": self.id,
"sender": self.sender.email,
"recipients": [user.email for user in self.recipients.all()],
"subject": self.subject,
"body": self.body,
"timestamp": self.timestamp.strftime("%b %-d %Y, %-I:%M %p"),
"read": self.read,
"archived": self.archived
}
views.py, this function i believe it returns the emails from my request:
#login_required
def mailbox(request, mailbox):
# Filter emails returned based on mailbox
if mailbox == "inbox":
emails = Email.objects.filter(
user=request.user, recipients=request.user, archived=False
)
elif mailbox == "sent":
emails = Email.objects.filter(
user=request.user, sender=request.user
)
elif mailbox == "archive":
emails = Email.objects.filter(
user=request.user, recipients=request.user, archived=True
)
else:
return JsonResponse({"error": "Invalid mailbox."}, status=400)
# Return emails in reverse chronologial order
emails = emails.order_by("-timestamp").all()
return JsonResponse([email.serialize() for email in emails], safe=False)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
# API Routes
path("emails", views.compose, name="compose"),
path("emails/<int:email_id>", views.email, name="email"),
path("emails/<str:mailbox>", views.mailbox, name="mailbox"),
]
My.js code where i use fetch:
document.addEventListener('DOMContentLoaded', function () {
// Use buttons to toggle between views
document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
document.querySelector('#compose').addEventListener('click', compose_email);
//code..
});
function compose_email() {
//code..
}
function load_mailbox(mailbox) {
// Show the mailbox and hide other views
document.querySelector('#emails-view').style.display = 'block';
document.querySelector('#compose-view').style.display = 'none';
// Show the mailbox name
document.querySelector('#emails-view').innerHTML = `<h3>${mailbox.charAt(0).toUpperCase() + mailbox.slice(1)}</h3>`;
//problem:
//i will change the 'sent' string in the future
fetch('/emails/sent')
.then(response => response.json())
.then(emails => {
console.log(emails);
});
}
self.timestamp.strftime("%b %-d %Y, %-I:%M %p")
You are using Python 3, but the code you were given was written for Python 2 (or by someone who didn't know all the difference with Python 3 so you might expect other hurdles down the road). They are used for non zero-padded versions of d and I.
In Python 3, -d and -I do not make sense to the parsing engine, and I don't think there are non zero-padded versions.
You can safely remove the -.
I am building a very basic CARTO application using Vue JS and Flask. The full code can be found in this github repository.
The application works like this:
The user select an option in a modal form and clicks on visualize button. This sends a Vue method called loadMap which sends a POST request with a query string (query computed property) value as a payload.
Then, it redirects the route to another template (map.html) and takes a variable (features) that is generated from a SQL API call.
This variable is a GeoJSON which will populate the data source of the map.
The problem is that after doing the redirection, the map template does not render. This is my Python code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__, static_folder='static', template_folder='templates')
#app.route('/')
def home():
"""Displays the homepage."""
return render_template('index.html')
#app.route('/query', methods=['POST'])
def query():
data = request.get_json()
query = data['query']
return redirect(url_for('map', query=query))
#app.route('/map', methods=['GET'])
def map():
query = request.args['query']
url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)
session = requests.Session()
r = session.get(url)
features = r.json()
return render_template('map.html', features=features)
if __name__ == '__main__':
app.run(debug=True)
It looks like the POST and GET call are done correctly, but then the redirection is not launched, so the map is not loaded:
How can I fix this problem? Is there a more elegant way to achieve this (loading a new website with data from an API call)?
The problem was located in my js code. So I fix it moving the map logic to the vue instance. I did also simplify the python code, in order to avoid using two templates. Now the app works, but I should refactor the js code to improve the performance (it takes too long to load) and scalalibility (the map logic should be moved again outside the vue instance). You can find the working example in this glitch repository.
The following snippet is my Flask python code...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__, static_folder='static', template_folder='templates')
#app.route('/')
def home():
"""Displays the homepage."""
return render_template('index.html')
#app.route('/data', methods=['GET'])
def data():
query = request.args.get('query')
url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)
session = requests.Session()
r = session.get(url)
features = r.json()
return features
if __name__ == '__main__':
app.run(debug=True)
... and this is my js code:
Vue.config.ignoredElements = [/as-\w+/];
const vm = new Vue({
el: "#app",
data: {
geometryType: 'cities',
map: false,
features: {}
},
computed: {
query: function() {
let table = ''
if (this.geometryType == 'cities'){
table = 'ne_10m_populated_places_simple';
} else {
table = 'world_borders';
}
return `select * from ${table}`
}
},
methods: {
loadMap: function() {
this.map = true;
this.$http.get('/data', {params: {query: this.query}} ).then(response => {
this.features = JSON.parse(response.bodyText);
console.log(this.features);
}, response => {
console.log('an error ocurred')
})
}
},
watch: {
features: function() {
const map = new mapboxgl.Map({
container: 'map',
style: carto.basemaps.voyager,
center: [10.151367,51.172455],
zoom: 2,
scrollZoom: false
});
const nav = new mapboxgl.NavigationControl({ showCompass: false });
map.addControl(nav, 'top-left');
carto.setDefaultAuth({
username: 'cartovl',
apiKey: 'default_public'
});
console.log(this.features);
const source = new carto.source.GeoJSON(this.features);
const viz = new carto.Viz();
const layer = new carto.Layer('layer', source, viz);
layer.addTo(map, 'watername_ocean');
}
}
})
Instead of a redirect try to render the template.
#app.route('/query', methods=['POST'])
def query():
data = request.get_json()
query = data['query']
return render_template('map.html', query=query)
Hope this helps :P
I am trying to send image files from React to my Django Rest Framework but Django Rest doesn't seem to be picking up my data.
It works fine when I am making a POST request directly from my Django REST Framework http://127.0.0.1:8001/api/paintings/photos but when I try to do it through react it throws a POST 500 error.
I am not sure if it has something to do with my content-type or it's something else.
This is my function in React
createPainting = (data) => {
console.log(data)
console.log(JSON.stringify(data))
const endpoint = "/api/paintings/photos"; //notice the endpoint is going to a relative request, (relative to where the final javascript built code will be)
const csrfToken = cookie.load("csrftoken");
if (csrfToken !== undefined) {
// this goes into the options argument in fetch(url, options)
let lookupOptions = {
method: "POST",
headers: {
"Content-Type": "multipart/form-data; boundary=63c5979328c44e2c869349443a94200e",
"Process-Data": "false",
"Accept": "multipart/form-data, application/json",
"X-CSRFToken": csrfToken
},
body: JSON.stringify(data),
credentials: "include"
};
fetch(endpoint, lookupOptions)
.then(response => {
return response.json();
})
this.clearForm()
.catch(error => {
console.log("error", error);
alert("An error occured, please try again later.");
});
}
};
The data that comes in looks like this:
{srcs: "yacht3.jpeg", title_id: "109"}
When I stringify it looks like this:
{"srcs":"yacht3.jpeg","title_id":"109"}
This is the full error message
Traceback (most recent call last):
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.NotNullViolation: null value in column "title_id" violates not-null constraint
DETAIL: Failing row contains (99, default.jpg, null, 1).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/generics.py", line 244, in post
return self.create(request, *args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 21, in create
self.perform_create(serializer)
File "/home/hzren/dev/t_and_b_website/src/paintings/views.py", line 132, in perform_create
serializer.save(user=self.request.user)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 940, in create
instance = ModelClass.objects.create(**validated_data)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/query.py", line 417, in create
obj.save(force_insert=True, using=self.db)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/base.py", line 729, in save
force_update=force_update, update_fields=update_fields)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/base.py", line 759, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/base.py", line 842, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/base.py", line 880, in _do_insert
using=using, raw=raw)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1125, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1285, in execute_sql
cursor.execute(sql, params)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/hzren/dev/t_and_b_website/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "title_id" violates not-null constraint
DETAIL: Failing row contains (99, default.jpg, null, 1).
It doesn't seem to be picking up my data inputs.
Here are the the related code in my paintings/views
class PaintingPhotosListCreateAPIView(generics.ListCreateAPIView):
queryset = PaintingPhoto.objects.all()
serializer_class = PaintingPhotoSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
pagination_class = PaintingPhotosPageNumberPagination
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def get_queryset(self):
# filter the queryset based on the filters applied
queryList = PaintingPhoto.objects.all()
title = self.request.query_params.get('title', None)
src = self.request.query_params.get('src', None)
return queryList
class PaintingPhotosTitleListCreateAPIView(generics.ListCreateAPIView):
queryset = PaintingPhoto.objects.all()
serializer_class = PaintingPhotoSerializer
lookup_field = 'title_id'
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def get_queryset(self):
title_id = self.kwargs['title_id']
return PaintingPhoto.objects.filter(title_id=title_id)
class PaintingPhotosSpecificDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = PaintingPhoto.objects.all()
serializer_class = PaintingPhotoSerializer
lookup_field = 'id'
permission_classes = [IsOwnerOrReadOnly]
Here is the related code in paintings/serializers.py
class PaintingPhotoSerializer(serializers.ModelSerializer):
title_name = serializers.CharField(source='title', read_only=True)
photo_title_url = serializers.HyperlinkedIdentityField(
view_name='paintings-api:photos-title-list',
read_only=True,
lookup_field='title_id'
)
photo_specific_url = serializers.HyperlinkedIdentityField(
view_name='paintings-api:photos-specific-detail',
read_only=True,
lookup_field='id'
)
owner = serializers.SerializerMethodField(read_only=True)
class Meta:
model = PaintingPhoto
fields =[
'title_id',
'src',
'title_name',
'photo_title_url',
'photo_specific_url',
'owner',
]
def get_owner(self, obj):
request = self.context['request']
if request.user.is_authenticated:
if obj.user == request.user:
return True
return False
Thanks so much in advance!