I'm trying to, using the Shopify Python library (which isn't that well documented), set a Metafield value that's currently a type single-line-text to either "" or Nil.
I've tried these solutions, and neither of them worked. My metafield definition will update to any other value I submit, but if I try submitting "" or None as the value, it will not change.
def add_order_metafield(tag, value):
metafield = shopify.Metafield({
'key': tag,
'value': value,
'type':'single_line_text_field',
'namespace':'custom'
})
return metafield
#doesn't work
customer.add_metafield(add_order_metafield('date', ''))
#doesn't work
customer.add_metafield(add_order_metafield('date', None))
#works as intended
customer.add_metafield(add_order_metafield('date', "None"))
Any advice here would be helpful.
Related
I have one API GET method integrated with lambda, in lambda integration mapping template.
mapping template:
{
"name" : "$input.params('name')",
"std_out" : "$input.params('std_out')"
}
condition is to set std_out default value to none but if user sends something in std_out then users values will be assign to it.
I'm not getting how to make std_out default to none but still accepts input if user pass any.
Things that I tried:
One way I think is instead of using GET, I will use POST method and will not use any mapping template. but this is not standard way.
I can ask User to send None if not passing any values, but still exploring if I can do something on my level to reduce the overhead from user.
So Is there any solution using GET method.
Although VTL variables seem to allow for an alternate value when empty, apparently API Gateway does not support that and fails to transform request.
The next best option is to use an inline if/else condition to perform the same:
## setting to a variable for readability, but not strictly necessary
#set( $std_out = $input.params('std_out') )
{
"name" : "$input.params('name')",
"std_out": #if( $std_out != '' )"$std_out"#{else}"None"#end
}
In case you want to skip passing the field if the user did not pass it, wrap the whole field inside the if/else:
{
## putting before 'name' so we don't have to deal with the comma there
#if( $input.params('std_out') != '' )
"std_out": "$input.params('std_out')",
#end
"name" : "$input.params('name')"
}
#parser_classes([MultiPartParser, FormParser])
#api_view(['POST', ])
def product_list(request):
print(request.POST.get('key'))
print(request.data.get('key'))
print(request.FILES)
When I am sending form data with value of key=null it displays null as string but didn't convert to None what should I do. The work around that I have to do
is something like
if request.data.get('key', None) in ['null', None]:
#then do something
But this doesn't seem to be a clean way of doing this. So what should I do?
I expected that django or django rest framework will automatically convert null to None.
There is no such thing as null/none in HTTP form-data content (in fact there's no such thing as types in the way we'd usually understand, though there can be a content-type associated with each item).
So what happens here is on the javascript side the null gets converted to a string, added to the data, sent to the server, which just gets a null string without any more information.
Generally, "null" items would be missing entirely, alternatively, they would have an empty value associated with them.
Either way, this is not an issue with django.
I made a small workaround to solve this issue by designing a middleware. I dont know if its good but it worked for me. I made it first mutable, changed it then made immutable again.
Note : if data sent is nested json you have to alter it to handle json recursively.
from django import http
from django.utils.deprecation import MiddlewareMixin
class NullStringToNoneMiddleware(MiddlewareMixin):
"""Responsible for converting all string null values to None"""
def process_request(self, request):
request.POST._mutable = True
for j in request.POST:
if request.POST[j] == 'null':
request.POST[j] = None
request.POST._mutable = False
Codenerix
Has anyone knows how to use correctly ng-readonly in a GenModelForm when coming from a sublist tab (GenList) who calls a GenCreateModal windows?
Structure is a master-detail, sublist tab has pk of master table and calls GenCreateModal with this pk argument of master table.
GenCreateModal receives pk argument in his asociated form (the mentioned GenModelForm) and can use it. The goal is to disable field with ng-disabled if pk argument of master table is filled. This way when create from another list of detail table without arguments, field can be filled with a value selecting it with the dropdown, and when coming from master table it cannot be modified and it will be assigned to master pk value.
I tried to do it that way:
First assign 'client' on GenCreateModal with:
def get_initial(self):
client = self.kwargs.get('pk', None)
if client:
self.kwargs['client'] = client
return self.kwargs
Then read it on the GenModelform with:
def __init__(self, *args, **kwargs):
super(DetailForm, self).__init__(*args, **kwargs)
if kwargs.get('initial', None) and kwargs['initial'].get('client', None):
self.fields['client'].widget.attrs[u'ng-readonly'] = 'true'
But it do not work with dropdown fields. Field can be modified.
Cause is that in templatetags_list.py of codenerix we have:
def inireadonly(attrs, i):
field = ngmodel(i)
return addattr(attrs, 'ng-readonly=readonly_{0}'.format(field))
This code set ng-readonly to "true readonly_client" instead of "true" when it comes with value "true" from GenModelForm, values are concatenated.
I found a workaround with:
self.fields['client'].widget.attrs[u'ng-readonly'] = 'true || '
this way the end value will be "true || readonly_client" that result on "true" as desired when evaluated, but I think it is not the proper way.
On my personal fork of django-codenerix I have changed the function to (functions is on two py files, should change both):
def inireadonly(attrs, i):
field = ngmodel(i)
if attrs.get('ng-readonly', None) is None:
attrs = addattr(attrs, 'ng-readonly=readonly_{0}'.format(field))
return attrs
This way it respects the value when it comes filled form GenModelForm, but I'm not sure about inconveniences and collateral effects. For example when want to concatenate conditions, with that change should read old value, concatenate manually and set new value. I think it should be a better way to do it and 'ng-readonly=readonly_{0}'.format(field) should have a functionality that I haven't discovered yet. Don't want to lose it when I discover it. So I revert the change and look for another solution.
Currently I'm using
self.fields['client'].widget.attrs[u'ng-disabled'] = 'true'
and it goes OK, I'm using this way and I have no problem now, but I'm curious about the way to use ng-readonly if I need it on the future. That's because with ng-readonly we can select text on fields with the mouse for example and can not select it with ng-disabled. In some cases it could be of interest.
Has anyone knows how to use ng-readonly in a correct way?
Has anyone knows the functionality of 'ng-readonly=readonly_{0}'.format(field)?
You can define an extra attribute to your fields in your forms. Add {'extra': ['ng-disabled=true']} in the field of your GenModelForm, inside your __groups__ method. Example:
def __groups__(self):
g = [
(_('Info'), 12,
['client', 6, {'extra': ['ng-disabled=true']}],
)
]
return g
You should use ng-disabled as you are doing. This is the way we do it in Django Codenerix Example # Gibhub (lines 41 and 42) and this is how it has been developed for StaticSelects (line 228) as well.
I've looked at documentation, and have searched Google extensively, and haven't found a solution to my problem.
This is my readRSS function (note that 'get' is a method of Kenneth Reitz's requests module):
def readRSS(name, loc):
linkList = []
linkTitles = list(ElementTree.fromstring(get(loc).content).iter('title'))
linkLocs = list(ElementTree.fromstring(get(loc).content).iter('link'))
for title, loc in zip(linkTitles, linkLocs):
linkList.append((title.text, loc.text))
return {name: linkList}
This is one of my MongoAlchemy classes:
class Feed(db.Document):
feedname = db.StringField(max_length=80)
location = db.StringField(max_length=240)
lastupdated = datetime.utcnow()
def __dict__(self):
return readRSS(self.feedname, self.location)
As you can see, I had to call the readRSS function within a function of the class, so I could pass self, because it's dependent on the fields feedname and location.
I want to know if there's a different way of doing this, so I can save the readRSS return value to a field in the Feed document. I've tried assigning the readRSS function's return value to a variable within the function __dict__ -- that didn't work either.
I have the functionality working in my app, but I want to save the results to the Document to lessen the load on the server (the one I am getting my RSS feed from).
Is there a way of doing what I intend to do or am I going about this all wrong?
I found out the answer. I needed to make use of a computed_field decorator, where the first argument was the structure of my return value and deps was a set which contained the fields that this field was dependent on. I then passed the dependent fields into a function's arguments and there you have it.
#fields.computed_field(db.KVField(db.StringField(), db.ListField(db.TupleField(db.StringField()))), deps=[feedname, location])
def getFeedContent(a=[feedname, location]):
return readRSS(a['feedname'], a['location'])
Thanks anyway, everyone.
I have a QTreeView GUI based on editabletreemode.py in the PyQt examples. Inside the model, I re-implemented setData() for my need: for some out-of-bound value, I'm returning False, otherwise, it returns True
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role != QtCore.Qt.EditRole:
return False
item = self.getItem(index)
result = item.setData(index.column(), value)
if result:
self.dataChanged.emit(index, index)
self.modified = True
print "setData() returning ", result
return result
Problem is, even when setData is returning False, GUI still accepts the changed value. So I now have inconsistent data between the model and view. What would make sense to me is that when setData() return False to reject the value, view should revert back to old value. Is this possible?
[SOLVED]
Actually the return value of setData() doesn't seem to matter. The QTreeView seem to call data() to re-retrieve the value afterwards anyway. The problem I was having was because setData() changed the internal data even though it returned False.
If somebody could explain to me what is the return value of setData() is used for, that'd be great.
The only issue I can see is the signature of .setData(), which is .setData(index, value, role). Neither your code snippet nor the description of your problem are verbose enough to say anything else.
Edit: Indeed, after looking at the Qt sources, I stand corrected. Unlike I've stated before this edit, the return value of .setData() is not actually used by the view.
The data is committed to the model by .setModelData() of the delegate. Normally, Qt uses a QStyledItemDelegate, whose .setModelData() method actually ignores the return value of .setData(). Thus the view does indeed not care for whether the data was successfully set. When the editor for a cell in the view is closed, the view just displays whatever is now the value of that cell (as retrieved by .data()).
However, the return value of .setData() is still important, and well-behaving models should take care to return a proper value. Models generally abstract data sources, and are in and by themselves independent from views. Thus models are also accessed directly, and in this case, the caller needs to check the return value of .setData() to know, whether the operation was successful.