I don't know how to ask this but is very simple
I have an entity called "State" and another entity called "City".
I'm doing a query to get specific cities with a given parameter:
cities = City.objects.filter(code__exact=12345).values("id","name","state")
And then I serialize the list ( or dict? = in order to get them via JSON:
for c in cities:
result.append(c)
return HttpResponse(json.dumps(result))
The problem is I'm getting only the state ID but I need another attributes from this object, how I can initialize the state object inside the city or at least get specific attributes from state object.
The result from a values() call is a ValueQuerySet, which is special in a few ways. One of them is:
A ValuesQuerySet is useful when you know you’re only going to need
values from a small number of the available fields and you won’t need
the functionality of a model instance object. It’s more efficient to
select only the fields you need to use.
The part in bold is important. It means that the result of the queryset will not have the instances of the models, you have to tell it exactly what you need to be fetched.
So, if you know the fields of the state model you want in your result, you can add them in your values clause. If you just put state, it will give you the state id, which is the default identity field.
cities = City.objects.filter(code__exact=12345).values("id",
"name",
"state__name",
"state__id")
If you are doing this just to convert the results to json, use the built-in serializers:
from django.core import serializers
result = serializers.serialize('json',
City.objects.filter(code__exact=12345),
fields=('id', 'name', 'state__name', 'state__id'))
Related
For some contrived reason I have two QuerySets which match up in row-order, but don't have a shared foreign key, so a join is not possible. I don't have the ability to add a key here, so I'd like to do a "hstack" of the two results and display as a table. This is easy with jinja templating, but I'd like to use the convenience functions of tables2 (e.g. sorting, etc) and I would like to still retain the ability to do foreign key traversal on each queryset.
Equivalently, consider providing a QuerySet and a list of external data that is the result of an operation on that QuerySet.
qs = ModelA.objects.filter( ... ) # queryset
ext_data = get_metadata_from_elsewhere(qs) # returns a list of dict
# len(qs) == len(ext_data)
For example, with two models I can create a Mixin:
class ModelATable(tables.Table):
class Meta:
model = ModelA
class ModelBTable(ModelATable, tables.Table):
class Meta:
model = ModelB
Which produces a rendered table with the fields from both models. If I supply ModelBTable(query_model_b) then only those fields are displayed as expected, and similarly for ModelBTable(query_model_a). How do I provide both query_model_a and query_model_b?
Also if there's an easy way to do hstack(query_a, query_b) then that seems like it'd be easier. Providing a dictionary of the combined results isn't great because I lose access to foreign keys, but I suppose I could add some logic to do that while generating the merged dictionary? But it's nice that tables2 automatically infers things based on the model field type, and I'd lose that.
I assume internally tables.Table just iterates through the provided data and tries to access by key. So I think I need to provide a data object that can resolve names from either model?
EDIT: Seems like defining the columns to be returned and providing a custom accessor might do the job, but it seems like overkill and I don't know which functions ought to be overridden (resolve, at least).
I have two classes declared as follows:
from mongoengine import Document, fields, DynamicDocument
class Booking(DynamicDocument):
booking_id=fields.StringField(required=True)
pickup_timestamp=fields.DateTimeField()
class Assignment(Document):
created_timestamp=fields.DateTimeField(default=datetime.datetime.utcnow)
pickup_time=fields.DateTimeField()
bookings=fields.ListField(fields.ReferenceField(Booking))
My application allows a user to club Bookings together under an Assignment object, by selecting the Booking objects from a list on the UI.
When creating the assignment object I automatically set the pickup time to the least value from the Booking pickup_timestamp like so -
assignment.pickup_time = min([booking.pickup_timestamp for booking in assignment.bookings])
However I also need to set other attributes on the assignment object based on other fields in the earliest Booking object.
My question - Is there a way to sort a ListField containing ReferenceFields by a field on the referenced objects?
I did find this answer, however it does not talk about ReferenceFields in the ListField. Tried setting the field type to SortedListField as well, but I wasn't able to figure out how to specify which key to sort on.
Solved with -
assignment.bookings=sorted(assignment.bookings, key=lambda k: k.pickup_timestamp)
Which is pretty much the same as this answer. I didn't know that the MongoEngine ListField behaves exactly like a dictionary in this regard!
If there is a more efficient/better way to do this, would be very keen to know!
I have the following models:
class Company(ndb.Model):
name = ndb.StringProperty(indexed=False)
# some other fields
class User(polymodel.PolyModel):
company = ndb.KeyProperty(kind=Company)
# some other fields
class Object(ndb.Model):
user = ndb.KeyProperty(kind=User)
# some other fields
Now I have a user and I want to query Objects that are associated with other Users in the same company like this:
Object.query(Object.user.company == user.company)
Of course, this doesn't work, since Object.user is a key and I cannot access anything beyond that.
Is there any way to do it? I only need the company key, I was thinking on a ComputedProperty but I'm not sure if it's the best solution. Also, it would be better to query based on any field in company.
You need to denormalize and store redundant information, as the datastore doesn't support joins.
For instance given your models above, a user can only be a member of one company, if you really need to search all objects whose user is a member of a particular company then store the company key in the Object.
Use a computed property if that works best for you.
Alternately use a factory that always takes the User as a argument and construct Object that way.
I have two models:
class BusinessCard(models.Model):
name = models.CharField(_("name"),null=True,max_length=50)
class Contacts(models.Model):
businesscard_id = models.OneToOneField(BusinessCard,null=True,blank=True,related_name='contact_detail',db_column="businesscard_id")
bcard_json_data = JsonField(null=True)
I just want access contacts model data using business card model:
target_bacard=BusinessCard.objects.filter(id=target_bacard_id).select_related()
When we access the target_bacard.contact_detail it gives key errors.
How can I get the contacts data using target_bacard queryset.
use get() instead of filter() like:
target_bacard = BusinessCard.objects.get(id=target_bacard_id)
target_bacard.contact_detail
If you want to access the Contacts instance that is in the 1-to-1 relationship with a BusinessCard instance bacard, use the related name you specified in Contacts:
contact = bacard.contact_detail
Also, you have some misleading names: Contacts should rather be Contact since an instance of this model represents only one contact. And its field businesscard_id would better be named businesscard (note that the table column will be called businesscard_id at the database level automatically in that case and store the id of the related businesssscard) because in the ORM you get a BusinessCard model instance when you access it, and not just its id.
You have not passed related model (field) argument to select_related()
target_bacard=BusinessCard.objects.filter(id=target_bacard_id).select_related('contact_detail')
Assuming id of BusinessCard is unique, you may want to use ...objects.get(id=target_bacard_id) inplace of ...objects.filter(id=target_bacard_id). Anyway select_related() will work on both ways.
select_related() is used for saving database query.
here is the documentation
I have the following in my model:
class info(models.Model):
add = models.CharField(max_length=255)
name = models.CharField(max_length=255)
An in the views when i say
info_l = info.objects.filter(id=1)
logging.debug(info_l.name)
i get an error saying name doesnt exist at debug statement.
'QuerySet' object has no attribute 'name'
1.How can this be resolved.
2.Also how to query for only one field instead of selecting all like select name from info.
1. Selecting Single Items
It looks like you're trying to get a single object. Using filter will return a QuerySet object (as is happening in your code), which behaves more like a list (and, as you've noticed, lacks the name attribute).
You have two options here. First, you can just grab the first element:
info_l = info.objects.filter(id=1)[0]
You could also use the objects.get method instead, which will return a single object (and raise an exception if it doesn't exist):
info_l = info.objects.get(id=1)
Django has some pretty good documentation on QuerySets, and it may be worth taking a look at it:
Docs on using filters
QuerySet reference
2. Retrieving Specific Fields
Django provides the defer and only methods, which will let you choose specific fields from the database, rather than fetching everything at once. These don't actually prevent the fields from being read; rather, it loads them lazily. defer is an "opt-in" mode, which lets you specify what fields should be lazily loaded. only is "out-out" -- you call it, and only the fields you pass will by eagerly loaded.
So in your example, you'd want to do something like this:
info_l = info.objects.filter(id=1).only('name')[0]
Though with a model as simple as the example you give, I wouldn't worry much at all about limiting fields.