Django: get object with empty column - python

I'm looking to do something like this:
u = User.objects.filter(name__isnull=True)[0]
The default value in MySQL for name is None. I also tried:
u = User.objects.filter(name=None)[0]
Neither have returned anything, aka, IndexError: list index out of range. How do I get an object with no value set as the name?

Even thought MySQL says the default value is None, Django used "" as the default, so I used:
User.objects.filter(name="").first()

You are missing some key concepts.
IndexError: list index out of range
This error is not a error looking in the db, this error is given because you are trying to do something with an index of array which does not exist.
a = [1,2,3]
a[0] = 1
a[2] = 2
a[3] = 3
a[4] = IndexError: list index out of range
a[n] = IndexError: list index out of range
you can do normaly:
u = User.objects.filter(name=None)
In the DB if you set Null = True and blank = True (i don't recommend this) in the models you can have 'name=None' and 'name=""'
The problem is you are supposing it must be at least one User with your params, for that you are adding the [0] to retrieve a user instance instead a queryset.
If you expect to retrieve only and only one item of the query you must use the .get, (normally used searching pk, if more than one item is returned it gives an error)
u = User.objects.get(name=None)
but, if you know more than one item can exist in your with the filters, (for instance, the name not the pk) and you only care about the first you use the .first method, and later you check if exist.
User.objects.filter(name="").first()

Related

Is there a way to set index 1 in a list when index 0 hasnt been defined

In Java ByteCode there is an opcode called "istore_1", which stores the top value of the stack into index 1 of the local variables, a list. I am trying to replicate this in python, but if you set index 1 of an empty list, its gonna set index 0 rather than index 1. My idea was to check if the first index of the list is empty, and if it is set it to like "emptyindex" or something, but after I did some research, I didnt find a way to check if an index is empty. My question is now how to store a value into index 1 of a list, even if index 0 hasnt been set, and set index 0 to "emptyindex" as a placeholder. Thanks a lot :D
local_variables = []
stack = [1]
user = input("Enter instruction")
if user == "istore_1":
local_variables.insert(1, stack[0])
print(local_variables)
You can use a function to manipulate your list:
def expand(a_list, index, value, empty=None):
l = len(a_list)
if index >= l:
a_list.extend([empty]*(index + 1 - l))
a_list[index] = value
local_variables = []
expand(local_variables, 1, 'str')
print(local_variables)
Output:
[None, 'str']
In Java bytecode, method headers contain a field which gives the maximum size of the local variable table that method uses. So you can just predeclare a list like [None] * MAX_LOCALS. Or you can just do [None] * 65535, since that's the maximum possible local variable table size. Or you can just use a dictionary so you don't have to worry about unset indexes entirely.

How it can modify formset's forms in an iteration

As far as I know if you iterate over a list and update its element, you dont update list itself.
list_var = ['a','b','c']
for l in list_var:
l = 'x'
print list_var
it prints out ['a', 'b', 'c'], not X's
Below code belongs to one of my project.
if hasattr(self.model, 'get_disabled_always_fields'):
for field in self.model.get_disabled_always_fields():
for form in self.formset_instance:
try:
form.fields[field].widget.attrs['readonly'] = True
except KeyError as e:
pass
It updates the list element and it effect the list we were iterating.
Question is , why formset forms affected by for loop modifications.
How variable references work
a = 1 really just means "make a an alias for the value carried by the expression 1". a = 1 + 2 really just means "evaluate 1 + 2 and then make a and alias for the result of that.
However, a[0] = 1 means "set the first value of a to the expression 1".
So, if you're looping through a list, you're essentially going through each value in the iterable and for each value, you set form to that value. Doing form = a within the list just changes the meaning of form. Doing form[0] = a modifies form.
If you don't want it to be modified, consider cloning form at the beginning of the loop using form = form[:].
I hope the concepts of how variables work in this case is now clear; it can be a bit confusing!
In first example you assign elements of list_var to l, then reassigning the same exact l variable.
In second example you operate with form.fields[field].widget.attrs['readonly'] and not field(by which you iterate). So if you would be doing:
for field in self.model.get_disabled_always_fields():
for form in self.formset_instance:
field = 'something' # or
form = 'something2'
nothing would change as it haven't in first example.

how to set the value of len(list_name)...?

I have a list that might return null values, then I have to iterate through it...ex:
for iter_aeh in range(len(alert_event_history_rows)):
alert_event_history_rows is a list and it can be null, so I want to set len(alert_event_history_rows) = 1 if alert_event_history_rows is a list of null values(0 rows).
But I get following error:
SyntaxError: can't assign to function call
for record_ae in alert_event_rows:
if len(alert_event_history_rows) == 0:
len(alert_event_history_rows) = 1
for iter_aeh in range(len(alert_event_history_rows)):
How to set the value of len(alert_event_history_rows)...?
Don't. Just handle the case where your list is empty with logic:
if alert_event_history_rows:
for item in alert_event_history_rows:
# do something
else:
# alert_event_history_rows was an empty list..
# do something else
This is a syntax error indeed:
len(alert_event_history_rows) = 1
... because you cannot make an assignment to a function call on the left hand side. It must be a variable that can receive the value. If what you really want to do is reinitialize that list to a single element null list, then you might do:
alert_event_history_rows = [None]
This should fix your problem
for record_ae in alert_event_rows:
for iter_aeh in range(max(len(alert_event_history_rows), 1)):

Django / Python, using iteritems() to update database gives strange error: "dictionary update sequence element #0 has length 4; 2 is required"

I'm trying to do a Django database save from a form where I don't have to manually specify the fieldnames (as I do in the 2nd code block), the way I am trying to do this is as below (1st code block) as I got the tip from another S.O. post. However, when I try this I get the error "dictionary update sequence element #0 has length 4; 2 is required", I even tried it, as below, with just a testdict dictionary, instead of the request.POST, but am still getting the error.. obviously the field value is fine since it works in the 2nd code block, so I am stumped as to why this is happening, would appreciate if anyone can shed any light on this for me... thanks
trying it this way gives the error:
testdict = {'name':'account_username','value':'vvvvvv'}
for name, value in testdict.iteritems():
if name != '' and name != 'top_select':
b = Twitter(**dict((name, value)))
b.save()
>>> dictionary update sequence element #0 has length 4; 2 is required
but this works fine:
b = Twitter(account_username='vvvvvv')
b.save()
Not sure what you are trying to do, but maybe you want something like this
b = Twitter(**{name: value})
But to get the equivalent to Twitter(account_username='vvvvvv') you would need something like this
Twitter(**{testdict['name'], testdict['value']})
where testdict would only contain a single entity to send to Twitter()
Then the code would look more like this
test_twits = [{'name':'account_username','value':'vvvvvv'},
{'name':'account_username','value':'wwwwww'},
]
for twit in test_twits:
name = twit['name']
value = twit['value']
if name != '' and name != 'top_select':
b = Twitter(**{name: value})
b.save()
Correct me if I am wrong.
From your second code snippet I take it that the Twitter class needs account_username as a keyword argument. When you are iterating through the dictionary using iteritems you are passing the name - i.e. the key of the dictionary as the keyword argument to the class. Isn't this wrong? The dictionary's keys are name and value, _not _ account_username. I believe you need the one of values from the dictionary to be passed as keyword argument, not one of the keys.
just do this:
dict(((name, value),))
'dict' takes a sequence of key, value tuples whereas you are giving it one key, value tuple.
The reason it says '... sequence element #0 has length 4' is because the key 'name' from testdict has a length of 4.

GQL does not work for GET paramters for keys

I am trying to compare the key to filter results in GQL in Python but the direct comparison nor typecasting to int works. Therefore, I am forced to make a work around as mentioned in the uncommented lines below. Any clues?
row = self.request.get("selectedrow")
#mydbobject = DbModel.gql("WHERE key=:1", row).fetch(1)
#mydbobject = DbModel.gql("WHERE key=:1", int(row)).fetch(1)#invalid literal for int() with base 10
#print mydbobject,row
que = db.Query(DbModel)
results = que.fetch(100)
mydbobject = None
for item in results:
if item.key().__str__() in row:
mydbobject = item
EDIT1- one more attempt that does not retrieve the record, the key exists in the Datastore along with the record
mydbobject = DbModel.gql("WHERE key = KEY('%s')"%row).fetch(1)
Am I correct in my assumption that you're basically just want to retrieve an object with a particular key? If so, the get and get_by_id methods may be of help:
mydbobject = DbModel.get_by_id(int(self.request.get("selectedrow")))
The error "invalid literal for int()" indicate that the paramater pass to int was not a string representing an integer. Try to print the value of "row" for debuging, I bet it is an empty string.
The correct way to retrieve an element from the key is simply by using the method "get" or "get_by_id".
In your case:
row = self.request.get("selectedrow")
mydbobject = DbModel.get(row)

Categories