#Django - 'list' object has no attribute 'id' - django

I have this code,
def delivery_date(request):
today = datetime.today().date()
results = [get(today)]
stages = Stage.objects.prefetch_related('Stage').all()
for i in range(3):
results.append(get(results[i]))
results = [{'date': i} for i in results]
stages = [{'menu': s} for s in stages]
for i in results:
for stage in stages:
stage['id'] = stage['menu'].id
stage['name'] = stage['menu'].name
stage['desc'] = stage['menu'].desc
stage['menu'] = stage['menu'].Stage.filter(
delivery_date__exact=i['date'])
stage['menu'] = serializers.serialize('python', stage['menu'])
i['menu'] = stages
i['date'] = i['date'].strftime('%b %-d')
return JsonResponse(results, safe=False)
But the results says,
this image
But if the results has only one date, it works.
Like this,
def delivery_date(request):
today = datetime.today().date()
results = [get(today)]
stages = Stage.objects.prefetch_related('Stage').all()
# for i in range(3):
# results.append(get(results[i]))
results = [{'date': i} for i in results]
stages = [{'menu': s} for s in stages]
for i in results:
for stage in stages:
stage['id'] = stage['menu'].id
stage['name'] = stage['menu'].name
stage['desc'] = stage['menu'].desc
stage['menu'] = stage['menu'].Stage.filter(
delivery_date__exact=i['date'])
stage['menu'] = serializers.serialize('python', stage['menu'])
i['menu'] = stages
i['date'] = i['date'].strftime('%b %-d')
return JsonResponse(results, safe=False)
The results,
[
{
"date" : Oct 25,
"menu" : [
{
"menu" : [
{
"model" : backend.product,
"pk" : 13,
"fields" : {
"name" : Tasty Tempeh,
"desc" : Nasi, Ayam, Wortel, Buncis, Bawang Merah, Bawang Putih, Daun Salam, Serai, Minyak Wijen, Minyak Kelapa Sawit.,
"desc_detail" : ,
"delivery_date" : 2019-10-25,
"avatar" : ,
"stage" : 1
}
}
],
"id" : 1,
"name" : Porridge,
"desc" :
}
}
]
What's wrong with my logic? Can Anyone helps?

it is just you missed that menu is a Dict which has a list as value say temp
and that temp file has a dict at its 0 indexes:
use the following :
stage['menu'][0]['id']

Related

Django JSONField nested greater than operation

Here's the structure of the JSONField - data I have.
data : {
"animals" : [
"animal_id" : 2321,
"legs" : [
{
"name" : "front",
"measured_at" : 1596740795.453353
},
{
"name" : "back",
"measured_at": 1596740795.453353
}
]
]
}
I need to find all records that match the following condition
legs-name = "front" OR
measured_at is greater than 6 hrs from now.
I have tried the following
six_hrs_ago = (datetime.utcnow() - timedelta(hours = 6)).timestamp()
obj = Model.objects.filter(data__has_key='animals').
filter(Q(data__animals__legs__name="front") | Q(data__animals__legs__measured_at__gt = six_hrs_ago))))
This doesn't work, and it fetches no record.
I also tried to just filter the records with legs - name - front, that doesn't work either
obj = Model.objects.filter(data__animals__contains=[{'legs': [{"name": "front"}]}])
Any ideas are appreciated.

Problem in rendering Multiple Drilldown in fusioncharts

I am using Django. I want use the drilldown feature in fusioncharts. I am able to get the first drilldown correctly. But when I code for the second drilldown it is showing "No data to display". Also the following code renders all the charts in the same type. But I want to render the child charts in different types. I am sharing the snippet below.
def chart(request):
dataSource = {}
dataSource['chart'] = {
"caption": "Top 10 Most Populous Countries",
"showValues": "0",
"theme": "zune"
}
dataSource['data'] = []
dataSource['linkeddata'] = []
sbc = MTD.pdobjects.values('Vertical', 'Channel','Brand','Sales_Value')
sbc_df = sbc.to_dataframe().reset_index(drop=True)#Trying to use filtered model for dataframe
sbc_df['Sales_Value']=sbc_df['Sales_Value'].astype(float)
chn_gb=sbc_df.groupby('Channel')['Sales_Value'].sum().reset_index()
channel=list(chn_gb['Channel'])
channel_val=list(chn_gb['Sales_Value'])
sbc_gb=pandas.pivot_table(sbc_df,index=['Vertical','Channel'],values=['Sales_Value'],aggfunc='sum').reset_index()
brd_gb=pandas.pivot_table(sbc_df,index=['Vertical','Channel','Brand'],values=['Sales_Value'],aggfunc='sum').reset_index()
for i in range(len(channel)):
data = {}
data['label'] = channel[i]
data['value'] = channel_val[i]
data['link'] = 'newchart-json-'+ channel[i]
dataSource['data'].append(data)
linkData2 = {}
linkData2['id'] = channel[i]
linkedchart2 = {}
linkedchart2['chart'] = {
"caption" : "Top 10 Most Populous Cities - " + channel[i] ,
"showValues": "0",
"theme": "fusion",
}
linkedchart2['data'] = []
sbc_filtered=sbc_gb[sbc_gb.Channel == channel[i]]
vertical_list=list(sbc_filtered['Vertical'])
vertical_val=list(sbc_filtered['Sales_Value'])
for k in range(len(sbc_filtered)):
arrDara2 = {}
arrDara2['label'] = vertical_list[k]
arrDara2['value'] = vertical_val[k]
arrDara2['link'] = 'newchart-json-'+ vertical_list[k]
linkedchart2['data'].append(arrDara2)
linkData1 = {}
# Inititate the linkData for cities drilldown
linkData1['id'] = vertical_list[k]
linkedchart1 = {}
linkedchart1['chart'] = {
"caption" : "Top 10 Most Populous Cities - " + vertical_list[k] ,
"showValues": "0",
"theme": "fusion",
}
linkedchart1['data'] = []
brd_filtered=brd_gb[(brd_gb.Channel == channel[i]) & (brd_gb.Vertical== vertical_list[k])]
brd_list=list(brd_filtered['Brand'])
brd_val=list(brd_filtered['Sales_Value'])
for j in range(len(brd_filtered)):
arrDara1 = {}
arrDara1['label'] = brd_list[j]
arrDara1['value'] = brd_val[j]
linkedchart1['data'].append(arrDara1)
linkData1['linkedchart'] = linkedchart1
dataSource['linkeddata'].append(linkData1)
linkData2['linkedchart'] = linkedchart2
dataSource['linkeddata'].append(linkData2)
print(dataSource)
column2D = FusionCharts("column2D", "ex1" , "700", "400", "chart-1", "json", dataSource)
return render(request, 'table.html',{'output':column2D.render()})
Kindly help me to achieve the successive drilldown correctly.
Thanks
In order to change the chart type for the child chart you need to use configureLink API method to set the child chart type, you can also set different chart at a different level, provided the datastructure for each chart is correct, here is how you can do
myChart.configureLink([
{ type: 'bar2d' },
{ type: 'line' },
{ type: 'pie2d' }
]);
Here is a demo - http://jsfiddle.net/x0c2wo7k/
Please note the above sample is using plain javascript

Odoo 11 one2many field not saving

In Odoo v10 this on_change method worked pretty well:
#api.onchange("partner_id")
def onchange_partner_id(self):
self.zapocet_line_pohledavky = False
self.zapocet_line_zavazky = False
account_move_line_obj = self.env['account.move.line']
val = {'value': {'zapocet_line_pohledavky': [], 'zapocet_line_zavazky': []}}
for statement in self:
if statement.partner_id:
domain = [('account_id.user_type_id.type', 'in', ('payable', 'receivable')), ('move_id.state', '=', 'posted'),
('partner_id.id', '=', statement.partner_id.id),]
line_ids = account_move_line_obj.search(domain, order="date asc")
for line in line_ids:
if line.amount_residual != 0 and line.credit > 0:
res = {
"move_line_id": line.id,
}
val['value']['zapocet_line_zavazky'].append(res)
if line.amount_residual != 0 and line.debit > 0:
qes = {
"move_line_id": line.id,
}
val['value']['zapocet_line_pohledavky'].append(qes)
self.zapocet_line_pohledavky = val['value']['zapocet_line_pohledavky']
return val
Does anybody have a clue why in v11 it loads the lines well, but they disappear on saving?

Multipart Request Unit Test with Tastypie

I've been trying to make an unit test for a multipart request but without success. What I've been doing is:
json_data = json.dumps({
"group_type" : "1",
"foo" : {
"visibility" : "4",
"description" : "#natureza tranquilidade",
"bars" : [
{
"x_pos" : 28.16901408450704,
"y_pos" : 38.87323943661972,
"bar_name" : "morro"
},
{
"x_pos" : 65.07042253521126,
"y_pos" : 65.07042253521126,
"bar_name" : "cachoeira"
}
]
}
})
photo = Image.new('RGB', (100, 100))
tmp_file = tempfile.NamedTemporaryFile(suffix='.jpg')
photo.save(tmp_file)
post_data = {
"json_data": json_data,
"photo": photo
}
response = self.client.post(
'/api/endpoint/',
data=post_data,
format='multipart',
authentication=self.get_credentials(self.user2)
)
But I get the following error:
File /venv/lib/python2.7/site-packages/tastypie/serializers.py", line 200, in serialize raise UnsupportedFormat("The format indicated '%s' had no available serialization method. Please check your ``formats`` and ``content_types`` on your Serializer." % format)
UnsupportedFormat: The format indicated 'json' had no available serialization method. Please check your ``formats`` and ``content_types`` on your Serializer.
Do you have any Ideas?
Fixed by uploading a real file and using Django's test API instead of the Tastypie's:
def test_post(self):
json_data = json.dumps({
"group_type" : "1",
"look" : {
"visibility" : "4",
"description" : "#natureza tranquilidade",
"photo_tags" : [
{
"x_pos" : 28.16901408450704,
"y_pos" : 38.87323943661972,
"brand_name" : "morro"
},
{
"x_pos" : 65.07042253521126,
"y_pos" : 65.07042253521126,
"brand_name" : "cachoeira"
}
]
}
})
with open('cards/tests/look_test.jpg') as photo:
response = self.client.client.post(
'/api/endpoint/',
data={'json_data': json_data, 'photo': photo},
HTTP_AUTHORIZATION=self.get_credentials(self.user2)
)
print response
self.assertEquals(response.status_code, 201)
Have fun!

Django form wont submit because of autocomplete widget field

I want to fill a text input in my form using an autocomplete widget that I have created using jquery ui. Everything works exactly how I want to, except when the form is submitted.
The problem is that when I submit the form, the text input is automatically reseted (I don't know why) and after that, the page reloads saying that the field is required (just validation working how it's supposed to). Of course, if it didn't reset the field everything would go fine.
I dont know if my select event of the autocomplete is working fine, here is the code:
select : function (e, ui) {
// I create a new attribute to store de database primary key of this option. This is
// usefull later on.
$('#%(input_id)s').attr('itemid', ui.item.real_value);
// I set the input text value's.
$('#%(input_id)s').val(ui.item.label);
}
Here is the full code of the autocomplete:
class AutocompleteTextInputWidget (forms.TextInput):
def media(self):
js = ("/js/autocomplete.js", "pepe.js")
def __init__(self, source, options={}, attrs={}):
self.options = None
self.attrs = {'autocomplete': 'off'}
self.source = source
self.minLength = 1
self.delay = 0
if len(options) > 0:
self.options = JSONEncoder().encode(options)
self.attrs.update(attrs)
def render(self, name, value=None, attrs=None):
final_attrs = self.build_attrs(attrs)
options = ''
if value:
final_attrs['value'] = escape(value)
if isinstance(self.source, list) or isinstance(self.source, tuple):
# Crea un Json con las opciones.
source = '['
for i in range(0, len(self.source)):
if i > 0:
source += ', '
source += '"' + self.source[i] + '"'
source += ']'
options = u'''
delay : %(delay)d,
minLength : %(minlength)s,
source : %(source)s
''' % {
'delay' : self.delay,
'minlength' : self.minLength,
'source' : source
}
elif isinstance(self.source, str):
options = u'''
delay : %(delay)d,
minLength : %(minlength)s,
source : function (request, response) {
if ($(this).data('xhr')) {
$(this).data('xhr').abort();
}
$(this).data('xhr', $.ajax({
url : "%(source_url)s",
dataType : "json",
data : {term : request.term},
beforeSend : function(xhr, settings) {
$('#%(input_id)s').removeAttr('itemid');
},
success : function(data) {
if (data != 'CACHE_MISS') {
response($.map(data, function(item) {
return {
label : item[1],
value: item[1],
real_value : item[0]
};
}));
}
},
}))
},
select : function (e, ui) {
$('#%(input_id)s').attr('itemid', ui.item.real_value);
$('#%(input_id)s').val(ui.item.label);
}
''' % {
'delay' : self.delay,
'minlength' : self.delay,
'source_url' : self.source,
'input_id' : final_attrs['id'],
}
if not self.attrs.has_key('id'):
final_attrs['id'] = 'id_%s' % name
return mark_safe(u'''
<input type="text" %(attrs)s/>
<script type="text/javascript">
$("#%(input_id)s").autocomplete({
%(options)s
});
</script>
''' % {
'attrs' : flatatt(final_attrs),
'options' : options,
'input_id' : final_attrs['id']
})
Tip: If I write some text without selecting it from the autocomplete, it still fails.
Another tip: If I set the field as optional it arrives to the view empty.
What should I do to make this work when I submit the form??? I have spent hours trying to
make this work. How can I make the form to recognise that I have allready filled that field?
Here is the code of the form:
test = forms.CharField(label = "autotest", widget = AutocompleteTextInputWidget('/myjsonservice'))
This is the rendered html:
<input type="text" autocomplete="off" id="id_test"/>
<script type="text/javascript">
$("#id_test").autocomplete({
delay : 0,
minLength : 0,
source : function (request, response) {
if ($(this).data('xhr')) {
$(this).data('xhr').abort();
}
$(this).data('xhr', $.ajax({
url : "/myjsonservice",
dataType : "json",
data : {term : request.term},
beforeSend : function(xhr, settings) {
$('#id_test').removeAttr('itemid');
},
success : function(data) {
if (data != 'CACHE_MISS') {
response($.map(data, function(item) {
return {
label : item[1],
value: item[1],
real_value : item[0]
};
}));
}
},
}))
},
select : function (e, ui) {
$('#id_test').attr('itemid', ui.item.real_value);
$('#id_test').val(ui.item.label);
}
});
</script>
Finally found the answer, the problem was that the "name" attribute wasn't rendered. Hence, the field could't get to the view as part of the request.
The final code of the autocomplete widget ended up like this:
class AutocompleteTextInputWidget (forms.TextInput):
def media(self):
js = ("/js/autocomplete.js", "pepe.js")
def __init__(self, source, options={}, attrs={}):
self.options = None
self.attrs = {'autocomplete': 'off'}
self.source = source
self.minLength = 1
self.delay = 0
if len(options) > 0:
self.options = JSONEncoder().encode(options)
self.attrs.update(attrs)
def render(self, name, value=None, attrs=None):
final_attrs = self.build_attrs(attrs)
options = ''
if value:
final_attrs['value'] = escape(value)
if isinstance(self.source, list) or isinstance(self.source, tuple):
# Crea un Json con las opciones.
source = '['
for i in range(0, len(self.source)):
if i > 0:
source += ', '
source += '"' + self.source[i] + '"'
source += ']'
options = u'''
delay : %(delay)d,
minLength : %(minlength)s,
source : %(source)s
''' % {
'delay' : self.delay,
'minlength' : self.minLength,
'source' : source
}
elif isinstance(self.source, str):
options = u'''
delay : %(delay)d,
minLength : %(minlength)s,
source : function (request, response) {
if ($(this).data('xhr')) {
$(this).data('xhr').abort();
}
$(this).data('xhr', $.ajax({
url : "%(source_url)s",
dataType : "json",
data : {term : request.term},
beforeSend : function(xhr, settings) {
$('#%(input_id)s').removeAttr('itemid');
},
success : function(data) {
if (data != 'CACHE_MISS') {
response($.map(data, function(item) {
return {
label : item[1],
value: item[1],
real_value : item[0]
};
}));
}
},
}))
},
select : function (e, ui) {
$('#%(input_id)s').attr('itemid', ui.item.real_value);
$('#%(input_id)s').val(ui.item.label);
}
''' % {
'delay' : self.delay,
'minlength' : self.delay,
'source_url' : self.source,
'input_id' : final_attrs['id'],
}
if not self.attrs.has_key('id'):
final_attrs['id'] = 'id_%s' % name
return mark_safe(u'''
<input type="text" name="%(name)s" %(attrs)s/>
<script type="text/javascript">
$("#%(input_id)s").autocomplete({
%(options)s
});
</script>
''' % {
'attrs' : flatatt(final_attrs),
'options' : options,
'input_id' : final_attrs['id'],
'name' : name
})
If someone knows how to improve this messy code it would be nice.
If someone knows about a nice widget documentation for django 1.4 (Other than the oficial, which sucks by the way) it would be nice too.
Bye, good coding everyone!!!