models.py
class club(models.Model):
name = models.CharField(max_length=30)
city = models.CharField(max_length=30)
premiere_leauge = models.BooleanField(default=False)
def __str__(self):
return self.name
Views.py
...
a = request.POST['club']
b = request.POST['city']
result = club.objects.all.get(name__exact=a, city__exact=b)
....
All is fine, however I believe result returns me:
def __str__(self):
return self.name
Whatsover, I would like an equivalent of 'SELECT * FROM APP_CLUB where name='something and city='something'; so i would be able to do further manipulation in django like:
if result[3] is True:
do_something()
As suggested in the offical documentation:
club.objects.filter(name='something')
It will return exactly the same as:
'SELECT * FROM APP_CLUB where name='something';
Example:
clubs = club.objects.filter(name__exact='something')
for club in clubs:
if club.premier_league:
do_something()
If you want to get only one club, then do it like this:
club = club.objects.get(name='something')
premier_league_value_of_club = club.premier_league
Use filter instead of get.
results = club.objects.filter(name__exact=a, city__exact=b)
You can then iterate over it to access all the model attributes like below
for result in results:
print result.name, result.city, result.premier_league
Also, according to PEP-8, you should name your class name should ideally be titlecase Club instead of lowercase club.
You're nearly there, I think you're missing the filter function here. You can use it like this :
a = request.POST['club']
b = request.POST['city']
result = club.objects.filter(name__exact=a, city__exact=b)
It will return you a query set with the actual database entries.
The __str__(self) function is used in transforming your query set entry into a string, whether you string-cast it or print it.
Then about this :
if result[3] is True:
do_something()
I don't get well what you mean about this, but if 3 is the id of the entry in the database, you then can do this :
if result.get(id=3).premiere_leauge:
do_something()
But you might want to check if the entry with the id exists first to avoid errors :
if result.filter(id=3).exists() and result.get(id=3).premiere_leauge:
do_something()
You should modify you query as shown below
result = club.objects.filter(name__exact=a, city__exact=b)
Good Luck !!
Related
I have a model like this one:
class Extension(models.Model):
name = models.CharField(max_length=32)
version = models.CharField(max_length=16)
#property
def path(self):
return something
I would like to get an Extension queryset containing only the last version for each name and then get a tuple (name, path) for each of these last recent Extension.
I tried
latests = Extension.objects.values('name').annotate(last=Max('version'))
but it gave me a dict without the properties access
How can i do that?
here's one way you could do it:
latests = Extension.objects.values('name').annotate(Max('version'))
q_statement = Q()
for pair in latests:
q_statement |= (Q(name=pair['name']) & Q(version=pair['version__max']))
extensions = Extension.objects.filter(q_statement)
I know if we have a model class, we can make a generate table and use:
class Meta:
model = MyModel
To display every field.
Now say if I have a list of dictionaries, instead of model, is there a similar way to do so?
(Since there are so many different dictionaries, which might be dynamically created, I don't wanna create a customized one each time :-))
You can create your own class that inherits from Table and define the fields you want there.
class JsonTable(Table):
json_key_1 = Column()
json_key_2 = Column()
Also django tables2 have a fields attribute but you can't use it if your data is an array of dicts.
I've been doing this too, here's a rough sketch.
Piggy-backing on top of django_tables2 is miles ahead of rolling your own!
Plus, I hook up the results to jquery FooTable plugin.
import django_tables2 as tables
counter = 0
def generate(li_dict):
#unique classname.
global counter
counter += 1
table_classname = "MyTableClass%s" % (counter)
class Meta:
#ahhh... Bootstrap
attrs = {"class": "table table-striped"}
#generate a class dynamically
cls = type(table_classname,(tables.Table,),dict(Meta=Meta))
#grab the first dict's keys
li = li_dict[0].keys()
for colname in li:
column = tables.Column()
cls.base_columns[colname] = column
return cls
#now, to make use of it...
li_dict = [dict(a=11,b=12,c=13),dict(a=21,b=22,c=23)]
cls = generate(li_dict)
table = cls(li_dict)
# below didn't work, wanted a whole bunch of django setup done first.
# but I fairly confident it would...
print table.as_html()
>>>django.core.exceptions.ImproperlyConfigured: {% querystring %} requires django.core.context_processors.request to be in your settings.TEMPLATE_CONTEXT_PROCESSORS in order for the included template tags to function correctly.
#this did...
print "%s" % table
>>><django_tables2.tables.MyTableClass1 object at 0x1070e1090>
i am sorry for poor english :), but a think which can help, actually with this we can transforme a numpy (matrix) in a generic django table2. By the way, thanks Pyeret for your help.
def convert_array_list_dict(arr):
_list = []
for i in xrange(0, arr.shape[0]):
_list.append(dict(enumerate(arr[i,:])))
for i in xrange(0,len(_list)):
for key in _list[i].keys():
_list[i]["col_" + str(key)] = _list[i].pop(key)
return _list`
This function above convert numpy array to list of dict
counter = 0
def list_dict(dict_):
global counter
counter += 1
table_classname = "MyTableClass%s" % (counter)
class Meta:
attrs = {"class": "paleblue", 'width': '150%'}
cls = type(table_classname, (tables.Table,), dict(Meta=Meta))
list_ = dict_[0].keys()
for colname in list_:
column = tables.Column()
cls.base_columns[colname] = column
return cls
This code make a generic table...and
t = np.loadtxt(doc.document)
tab = convert_array_list_dict(t)
table = list_dict(tab)
table_content = table(tab)
RequestConfig(request, paginate={'per_page': 30}).configure(table_content)
return render(request,'app/snippets/upload_file.html',{'document':document,'table_content':table_content})
Above we can see how use all code...
I am trying to use this way,
models.py
class Father(models.Model):
name = models.CharField(...)
def last_child_age(self):
children = self.child.order_by('-pk')
if len(children) > 0:
return find_Year(datetime.datetime.now()-children[0].birth_day)
return -1
class Child(models.model):
father = models.ForeignKey(Father, related_name='child')
birth_day = models.DateTimeField(auto_now_add=True)
views.py
def get_old_fathers(request):
father_list = Father.objects.filter(last_child_age__gte=15)
Returns:
Cannot resolve keyword
error.
What is the correct way of making this query other than iterating one by one.
You cant make queries using model class method (passing function to filter) in Django
If you need list of Father objects which have childs with age > 15 years:
d = datetime.date.today()
father_list = Father.objects.filter(
child__birth_day__lte=datetime.date(d.year-15, d.month, d.day))
Without adding flags to Child you can decide which is last (youngest) by making subqueries to child table. Annotation with max birthday (last son -> bigger birth_day date) can help. Try this query (im not test it):
from django.db.models import Max
father_list = Father.objects.annotate(max_birthday=Max('child__birth_day')
).filter(max_birthday__lte=datetime.date(d.year-15, d.month, d.day))
You have not posted your Child model and last_child_age code, but something like this should work:
Child.objects.filter(age__gte=15).prefetch_related('father')
last_child_age is a method, not a column. ORM queries generate SQL, and SQL don't know zilch about your models methods - how would the SQL database call back on your Python code ?
I'm using the bottle framework together with mongoengine.
I have an orders model :
class OrderDetail(Option):
orderDetailsQty = FloatField()
def to_dict(self):
return mongo_to_dict_helper(self)
class Order(Document):
userName = StringField(required=True)
orderDate = DateTimeField()
orderStatus = ListField(EmbeddedDocumentField(Status))
orderDetails = ListField(EmbeddedDocumentField(OrderDetail))
orderComments = ListField(EmbeddedDocumentField(Comment))
isActive = BooleanField()
def to_dict(self):
orderObj = mongo_to_dict_helper(self)
orderDetailList = []
for orderDetail in orderObj["orderDetails"]:
orderDetailList.append(orderDetail.__dict__)
orderObj["OrderDetails"] = orderDetailList
return (self)
When mongodb is queried I get an object which is then converted in to a dict by using the following function :
def mongo_to_dict_helper(obj):
return_data = []
for field_name in obj._fields:
if field_name in ("id",):
continue
data = obj._data[field_name]
if isinstance(obj._fields[field_name], StringField):
return_data.append((field_name, str(data)))
elif isinstance(obj._fields[field_name], FloatField):
return_data.append((field_name, float(data)))
elif isinstance(obj._fields[field_name], IntField):
return_data.append((field_name, int(data)))
elif isinstance(obj._fields[field_name], ListField):
return_data.append((field_name, int(data)))
else:
# You can define your logic for returning elements
pass
return dict(return_data)
I found this function after a long search in the internet. Later found out that this function also fails while defining a member as the ListField(EmbeddedDocumentField(obj)).
I also tried writing a condition for catching the specific case of EmbeddedDocumentField :
elif isinstance(obj._fields[field_name], EmbeddedDocumentField):
return_data.append(mongo_to_dict_helper(data))
but that didn't do any good either.
Anyone have a workaround for this issue ?
What about just using to_mongo method of an object to convert it to a dict?
object.to_mongo()
Expanding on #alexvassel's and #z0r's answers, calling .to_mongo() converts the object to a SON instance. Once you have it, you can call its .to_dict() method to convert it to a dictionary.
For example... (qset is a queryset that's returned from mongoengine, after e.g. Posts.objects.all()).
sons = [ob.to_mongo() for ob in qset]
for son in sons:
print str(son.to_dict())
import json
json.loads(yourobj.to_json())
Extending on #alexvassel's answer, to_mongo() method returns SON object, which you can convert to dict by calling its to_dict() method
object.to_mongo().to_dict()
you can custom method to convert object to dict
class Order(Document):
userName = StringField(required=True)
orderDate = DateTimeField()
orderStatus = ListField(EmbeddedDocumentField(Status))
orderDetails = ListField(EmbeddedDocumentField(OrderDetail))
orderComments = ListField(EmbeddedDocumentField(Comment))
isActive = BooleanField()
def as_dict(self):
return {
"user_name": self.userName,
"order_date": self.orderDate.strftime("%Y-%m-%d %H:%M:%S"),
}
now you can use obj.as_dict() to dict
orders = Order.objects.all()
datas = [each.as_dict() for each in orders]
combining all other answers,
import json
dict = {'data':[json.loads(ob.to_json()) for ob in qset]}
There can be two scenario.
when query returns CommandCursor object
**records = list(CursorObject)**
ex - Class.objects().aggregate({...})
when query returns BaseQuerySet object
**import json**
**records = json.loads(BaseQuerySetObject.to_json())**
ex - Class.objects().filter(..)
Looking at the bottom of the post you can see i have three classes. The code here is pseudo code written on the fly and untested however it adequately shows my problem. If we need the actual classes I can update this question tomorrow when at work. So ignore syntax issues and code that only represents a thought rather than the actual "code" that would do what i describe there.
Question 1
If you look at the Item search class method you can see that when the user does a search i call search on the base class then based on that result return the correct class/object. This works but seems kludgy. Is there a better way to do this?
Question 2
If you look at the KitItem class you can see that I am overriding the list price. If the flag calc_list is set to true then I sum the list price of the components and return that as the list price for the kit. If its not marked as true I want to return the "base" list price. However as far as I know there is no way to access a parent attribute since in a normal setup it would be meaningless but with sqlalchemy and shared table inheritance it could be useful.
TIA
class Item(DeclarativeBase):
__tablename__ = 'items'
item_id = Column(Integer,primary_key=True,autoincrement=True)
sku = Column(Unicode(50),nullable=False,unique=True)
list_price = Column(Float)
cost_price = Column(Float)
item_type = Column(Unicode(1))
__mapper_args__ = {'polymorphic_on': item_type}
__
def __init__(self,sku,list_price,cost_price):
self.sku = sku
self.list_price = list_price
self.cost_price = cost_price
#classmethod
def search(cls):
"""
" search based on sku, description, long description
" return item as proper class
"""
item = DBSession.query(cls).filter(...) #do search stuff here
if item.item_type == 'K': #Better way to do this???
return DBSession.query(KitItem).get(item.item_id)
class KitItem(Item):
__mapper_args__ = {'polymorphic_identity': 'K'}
calc_list = Column(Boolean,nullable=False,default=False)
#property
def list_price(self):
if self.calc_list:
list_price = 0.0
for comp in self.components:
list_price += comp.component.list_price * comp.qty
return list_price
else:
#need help here
item = DBSession.query(Item).get(self.item_id)
return item.list_price
class KitComponent(DeclarativeBase):
__tablename__ = "kit_components"
kit_id = Column(Integer,ForeignKey('items.item_id'),primarykey=True)
component_id = Column(Integer,ForeignKey('items.item_id'),primarykey=True)
qty = Column(Integer,nullable=False, default=1)
kit = relation(KitItem,backref=backref("components"))
component = relation(Item)
Answer-1: in fact you do not need to do anything special here: given that you configured your inheritance hierarchy properly, your query will already return proper class for every row (Item or KitItem). This is the advantage of the ORM part. What you could do though is to configure the query to immediatelly load also the additional columns which do belong to children of Item (from your code this is only calc_list column), which you can do by specifying with_polymorphic('*'):
#classmethod
def search(cls):
item = DBSession.query(cls).with_polymorphic('*').filter(...) #do search stuff here
return item
Read more on this in Basic Control of Which Tables are Queried.
To see the difference, enabled SQL logging, and compare your tests scripts with and without with_polymorphic(...) - you will most probably require less SQL statements being executed.
Answer-2: I would not override one entry attributed with one which is purely computed. Instead I would just create another computed attribute (lets call it final_price), which would look like following for each of two classes:
class Item(Base):
...
#property
def total_price(self):
return self.list_price
class KitItem(Item):
...
#property
def total_price(self):
if self.calc_list:
_price = 0.0
for comp in self.components:
_price += comp.component.list_price * comp.qty
return _price
else:
# #note: again, you do not need to perform any query here at all, as *self* is that you need
return self.list_price
Also in this case, you might think of configuring the relationship KitItem.components to be eagerly loaded, so that the calculation of the total_price will not trigger additional SQL. But you have to decide yourself if this is beneficial for your use cases (again, analyse the SQLs generated in your scenario).