fetch all null values for a object django - django

How should I search for all null values for a given object (name)?
model:
name = models.CharField(max_length=150,null=True,blank=True)
u_name=models.CharField(max_length=25,null=True,blank=True)
year=models.PositiveSmallInteger(blank=True,null=True)
I am looking to back populate some data through various 'lookups'.
It may or may not have value for various fields for a given object. I want to populate those fields that are null with the available values through lookups.
I can fetch one field that is null. But is there a way fetch all the null values for a give name 'rig'
u_name = Name.objects.filter(name='rig', u_name__isnull=True)
Thanks

Note that CharFields will store 'null' values as empty strings (https://docs.djangoproject.com/en/1.8/ref/models/fields/#null), so you may want to try the following:
u_name = Name.objects.filter(name='rig').filter(u_name=None)
or
u_name = Name.objects.filter(name='rig').filter(u_name="")
Update based on comments:
To get the Names with name='rig':
rigs = Name.objects.filter(name='rig')
then loop over empty u_names:
for u_name in rigs.filter(u_name=""):
# do things
and then loop over empty years:
for empty_year in rigs.filter(year=None):
# do things

Related

Is there any way I can avoid iterating over a query set with single value?

I get a queryset object every time i want some data from models.
So when i say,
"items = Items.object.get(value=value)"
I get --
"<QuerySet [<Item-name>]>"
I have to iterate through the queryset object to get the data and I do that with
"items[0]"
Is there any way I can avoid this?
Edit: I meant "items = Items.object.filter(value=value)"
first of all items = Items.objects.get(value=value) does not return a queryset,
rather it returns an object of <Items: Items object (1)>
To get the first(or just one result) or last date from the object, do this Items.objects.first() or Items.objects.last()
To get the desired data without using its index position, then you can filter it like this Items.objects.filter(value=value)
You are mistaken. items = Items.object.get(value=value) will not give you a queryset, but an object. items = Items.object.filter(value=value)
would give you a queryset.
Filter method will always give you a queryset, because; in order to minimize the need of database hits, django considers you might add additional filters through your code. So if you not execute that queryset, e.g. by using list(your_queryset) django never hits the database.
# when you are using 'get' in your query, you don't need to iterate, directly get an access to the field values
try:
items = Items.object.get(value=value)
except Items.DoesNotExist:
items = None
if items:
print(items.value)

How can i filter a column in Django using .filter?

I have the following line:
test = MyModel.objects.filter(user=request.user)
The problem with this line is that it will retrieve the whole row. What if i want to retrieve the data from a certain column? For example, instead of the whole row, i'm trying to retrieve the column email
I tried this, but it's not working: email = test.email
You can use .values_list('email', flat=True) [Django-doc], like:
test = MyModel.objects.filter(user=request.user).values_list('email', flat=True)
Then test is a QuerySet that wraps strings. But usually this is not good software design. Usually one retrieves and stores User objects, not column values. A model can add a lot of extra logic that prevents that certain values are stored, and it sometimes contains extra logic to validate, clean, etc.
If a User has a single MyModel, you can just use .get(..) instead, like:
the_email = MyModel.objects.get(user=user).email
or with .values_list:
the_email = MyModel.objects.values_list('email', flat=True).get(user=user)

Ordered list in Django

Can anyone help, I want to return an ordered list based on forloop in Django using a field in the model that contains both integer and string in the format MM/1234. The loop should return the values with the least interger(1234) in ascending order in the html template.
Ideally you want to change the model to have two fields, one integer and one string, so you can code a queryset with ordering based on the integer one. You can then define a property of the model to return the self.MM+"/"+str( self.nn) composite value if you often need to use that. But if it's somebody else's database schema, this may not be an option.
In which case you'll have to convert your queryset into a list (which reads all the data rows at once) and then sort the list in Python rather than in the database. You can run out of memory or bring your server to its knees if the list contains millions of objects. count=qs.count() is a DB operation that won't.
qs = Foo.objects.filter( your_selection_criteria)
# you might want to count this before the next step, and chicken out if too many
# also this simple key function will crash if there's ever no "/" in that_field
all_obj = sorted( list( qs),
key = lambda obj: obj.that_field.split('/')[1] )

Django: Sort and filter rows by specific many to one value

In the provided schema I would like to sort Records by a specific Attribute of the record. I'd like to do this in native Django.
Example:
Query all Records (regardless of Attribute.color), but sort by Attribute.value where Attribute.color is 'red'. Obviously Records missing a 'red' Attribute can't be sorted, so they could be just interpreted as NULL or sent to the end.
Each Record is guaranteed to have one or zero of an Attribute of a particular color (enforced by unique_together). Given this is a one to many relationship, a Record can have Attributes of more than` one color.
class Record(Model):
pass
class Attribute(Model):
color = CharField() # **See note below
value = IntegerField()
record = ForeignKey(Record)
class Meta:
unique_together = (('color', 'record'),)
I will also need to filter Records by Attribute.value and Attribute.color as well.
I'm open to changing the schema, but the schema above seems to be the simplest to represent what I need to model.
How can I:
Query all Records where it has an Attribute.color of 'red' and, say, an Attribute.value of 10
Query all Records and sort by the Attribute.value of the associated Attribute where Attribute.color is 'red'.
** I've simplified it above -- in reality the color field would be a ForeignKey to an AttributeDefinition, but I think that's not important right now.
I think something like this would work:
record_ids = Attribute.objects.filter(color='red', value=10).values_list('record', flat=True)
and
record_ids = Attribute.objects.filter(color='red').order_by('value').values_list('record', flat=True)
That will give you IDs of records. Then, you can do this:
records = Record.objects.filter(id__in=record_ids)
Hope this helps!

Django append to JSON after serializers.serialze has been run on a queryset

I am returning a JSON serialized queryset using the following queryset:
genome_parents = Genome.objects.filter(genes=cus_id)
where cus_id is the FK pointing to a companies table so I am retrieving all Genome objects related to the current working company. I return this data after a form has been posted via:
genome_parents = serializers.serialize('json', genome_parents, use_natural_keys=True)
However, I need the natural key for one of my foreign keys, but the id for another (both on the same model). So one field is displayed nicely, but the other isn't. So this does what I need except for one little thing, I need the plain id number so that I can pre-populate my FK form field.
One thought I had was to just append something like
genome_parents.append({'id':gene.id})
but that obviously doesn't work. Is there anyway I can augment the JSON so that I can include one more little piece of data (or change how I format the JSON)?
Greg
Just switch the order of the operations. And put the entire gene object into the list so it is properly serialized.
genome_parents = list( Genome.objects.filter(genes=cus_id) )
genome_parents.append(gene)
json_genome_parents = serializers.serialize('json', genome_parents, use_natural_keys=True)