lets suppose that some code in my view looks like this:
bar = Bar.objects.get(pk=1)
foos = bar.foo_set.filter(VERY_LONG_COMPLEX_FILTERING_LOGIC)
I would obviously want to clean the filter method a bit, by creating a custom method that does the same thing, like so:
bar = Bar.objects.get(pk=1)
foos = bar.foo_set.complexfilter()
Moving the custom method somewhere to a class would be perfect, but so far I couldn't find any mention of anything like that in the docs. Any suggestions?
Thank you in advance.
Placing it in bar's method seems good.
Related
I would like to solve a little problem with Django and QuerySet.
I have in my views this command :
query_car = Car.objects.get(pk=value)
But I want to get only one field from the CarModels, for example : color or another one but just one.
How I can handle my script in order to do that ?
Thank you so much !
You should use .values()
example:
query_car = Car.objects.filter(pk=value).values('color')
You are looking for the only() method.
Like so:
query_car = Car.objects.only("color").get(pk=value)
i have three classes. Place is foreignkey of Activity(where the activity takeplace), Park and Restarant are inherited from Place.
class Activity(Model):
place=ForeignKeyField('Place')
....
class Place(Model):
address=CharField(max_length=200)
....
class Park(Place):
ticket_price=Decimal()
....
class Restarant(Place):
manager_name=CharField(max_length=100)
how can i get the real type of 'Place' in a query on Activity,so i can get the additional attributes of child type.
activity_list= Activity.objects.all()
all the activity_list[n].place are 'Place' ,neither Park or Restarant, so i can't get 'ticket_price' or 'manager_name' directly.
i have checked the model-utils, and can't find a easy way to do this.
any help will be appreciated.
inspect.getmro(cls)
Return a tuple of class cls’s base classes, including cls, in method resolution order. No class appears more than once in this tuple. Note that the method resolution order depends on cls’s type. Unless a very peculiar user-defined metatype is in use, cls will be the first element of the tuple.
try:
import inspect
for activity in activity_list:
print inspect.getmro(activity.place)
or try :
for activity in activity_list:
print activity.place._type()
try:
activity_list= Activity.objects.all()
for act in activity_list:
for b in act.place.__class__.__bases__:
print b.__name__
I use Django Inheritance Managers for this, from django-model-utils. It allows you to do exactly what you want...you said you checked model-utils to do this, but it didn't work. It should work -- what did you try with django-model-utils? You need to add this line to the parent model of Place:
objects = InheritanceManager()
I haven't tried this with your exact model design, but have you tried something like:
places = Activity.objects.all().values_list('place_id', flat=True)
places_of_right_type = Place.objects.filter(pk__in=places).select_subclasses()
?
------ UPDATE --------
Not sure this will work, but throwing it out there as an idea...would only work for a get(), not all():
places = Activity.objects.get(pk=#).place.objects.select_subclasses()
The docs say that you can call select_subclasses() on the InheritanceManager itself, which is stored in .objects.
I have this code:
my_table = db.define_table('my_table',
Field('mt_table_id', 'id', requires=[IS_NOT_EMPTY()]),
I need to add something like requires= IS_LIST() to get a list e.g. ['a','b','c'] instead of ['a,b,c']. How is that done?
I ain't got what you meant, but perhaps you should look at custom validators section in web2py's book: http://www.web2py.com/books/default/chapter/29/07/forms-and-validators#Custom-validators
You may create a custom validator called IS_LIST() and change the "formatter" method to return a list in the way that you want.
If I have an action Application.show(tag: String), and also have a corresponding routing entry, how can I insert a link to this action to a template without crafting the url manually?
I would like to do something like magiclink(Application.show("tag")).
syntax:
<a href='#routes.Application.show("some")'>My link with some string</a>
By analogy you can also generate urls in your controllers. ie. for redirecting after some action:
public static Result justRedirect(){
// use as String
String urlOfShow = routes.Application.index().toString().
// or pass as a redirect() arg
return redirect(routes.Application.show("some"));
}
The format for putting a URL from your routes file in your html is as follow:
#routes.NameOfYourClass.nameOfyourMethod()
So, if in your routes file you have:
GET /products controllers.Products.index()
And your Products class looks like this:
public class Products extends Controller {
public Result index() {
return ok(views.html.index.render());
}
}
Your <a> should look like this:
Products
In addition: If your method can accept parameters, then you can of course pass them in between the parenthesize of your method like this: index("Hi").
I hope this answer is more clear to understand.
The accepted answer is right, but it doesn't cover the case where the controller is in a sub-package, i.e.: controllers.applications.MyFavouriteApplication.show()
Since I had a hard time finding the answer, I'll post it here.
To put a non-scoped link into a template, the proper pattern is #controllers.{sub-packages if any}.routes.{your class}.{your method}()
So in this case it would be #controllers.applications.routes.MyFavouriteApplication.show()
IF you were using the recommended Play pattern of using #Inject to create singleton controller objects, and IF you thought the correct answer was #controllers.applications.MyFavouriteApplication.show(), you would get an error like this:
Object MyFavouriteApplication is not a member of controllers.applications. Note: class MyFavouriteApplication exists, but it has no companion object.
Given that you had already supplied the #Inject() #Singleton annotation, this would seem like a very strange error indeed. It might make you question if you were building the project correctly. Determining the true cause could cost you considerably in blood and treasure.
Ah, as simple as #{routes.Application.show("tag")}.
I have a specification which essentially looks like this:
def "my example specification"(){
given:"some mocked object which depends on a object created in the where clause"
def display = mockDisplay()
and:"a activityt"
def activity = new ConfigActivity(display)
when:
activity.doStuff()
then:
1 * display.select()
where:
dependency << new Dependency()
}
private mockDisplay() {
def display = Mock(ConfigActivity.Display)
display.addDependency(dependency)
return display
}
I understand that that the "mockDisplay()" method is out of scope from the "where" clause. However since a few specifications tend to get rather cluttered with boilerplate code (not in this over simplified example offcourse) I really need some way to reuse my "given" statements and in doing so I would really like to make use of the Spock "where" clauses as well.
Is this doable? Or is there another way to go about this problem?
There is no magic way to access a data variable from a helper method, but you can pass it as a method parameter.