I am trying to "DRY" my code and would like to create a function to make my query dynamic.
The code that I currently use is :
rightone = []
for item in taglist: #taglist is a list of model instances, not relevant here
content = content.filter(tags__title=item.title) #tags here is a M2M key : my problem, content is a query
rightone.append(content)
tagproofquery = rightone[-1]
and I would like to convert it to:
def uniquetogether(queryset,data, model):
rightone = []
for item in queryset:
content = data.filter(tags__title=item.title) # <--- problem is here with tags
rightone.append(content)
tagproofquery = rightone[-1]
return tagproofquery
I have no idea how to replace my M2M "tags" as in tags__title=item.title with the "model" parameter of my function. I tried f strings but it failed miserably (of course).
Is there a way to do this? Many thanks
Related
How can I loop through form data where the ending part could be 1,2,3,4 and so on, and store in the DB without hardcoding the DB like below so each description would be on its own line but one person could post description1-10 and the other 10-27 and so on
for example instead of say this
order.description_1 = request.POST.get('description1')
order.length_1 = request.POST.get('length1')
order.width_1 = request.POST.get('width1')
order.depth_1 = request.POST.get('depth1')
order.weight_1 = request.POST.get('weight1')
order.description_2 = request.POST.get('description2')
order.length_2 = request.POST.get('length2')
order.width_2 = request.POST.get('width2')
order.depth_2 = request.POST.get('depth2')
order.weight_2 = request.POST.get('weight2')
currently the form passes request.POST.get('description1') and with a limit of request.POST.get('description5') but would like each description on its own row and not be subject to a hardlimit and uses a bit of javascript to append the x value to the name. The postdata form is also hardcoded so not using forms.py
The request.POST is a python dictionary, so you can loop through it like this:
for key, value in request.POST.items():
print(key, value)
# set the property for order
# you can work on key and change it if need
setattr(order, key, value)
For a better implementation of this requirement, you can use django forms with ArrayField fields:
django simple array field
how-to-define-arrayfield-to-django-forms
I have two models, ParentPage and ChildPage. I want to find the set of ParentPages where a field is_completed is True on the ChildPage.
Normally in Django, I could do something like
ParentPage.objects.filter(child_page__is_completed=True)
However, I don't think there is a join here for the Wagtail/Treebeard hierarchy.
I also thought you might be able to filter ChildPages by multiple ParentPages, e.g. ChildPage.objects.children_of([parent_ids]), but I can't see a way to do that either.
Is there a simpler way?
The Page table has path and url_path columns. If you find all children and strip the last part of the path or url_path, you can use that result to query the parent pages.
Path:
child_paths = ChildPage.objects.filter(is_completed=True).values_list("path", flat=True)
parent_paths = set([cp[:-4] for cp in child_paths])
pages = Page.objects.filter(path__in=parent_paths)
Url path:
child_urls = ChildPage.objects.filter(is_completed=True).values_list("url_path", flat=True)
parent_urls = set([url.rsplit('/', 1)[0] for url in child_urls])
pages = Page.objects.filter(url_path__in=parent_urls)
Disclaimer: untested code.
I'm trying to render a form with a combo that shows related entities. Therefore I'm using a ModelChoiceField.
This approach works well, until I needed to limit which entities to show. If I use a simple query expression it also works well, but things break if I use a raw SQL query.
So my code that works, sets the queryset to a filter expression.
class ReservationForm(forms.Form):
location_time_slot = ModelChoiceField(queryset=LocationTimeSlot.objects.all(), empty_label="Select your prefered time")
def __init__(self,*args,**kwargs):
city_id = kwargs.pop("city_id") # client is the parameter passed from views.py
super(ReservationForm, self).__init__(*args,**kwargs)
# TODO: move this to a manager
self.fields['location_time_slot'].queryset = LocationTimeSlot.objects.filter(city__id = city_id )
BUT, if I change that to a raw query I start having problems. Code that does not work:
class ReservationForm(forms.Form):
location_time_slot = ModelChoiceField(queryset=LocationTimeSlot.objects.all(), empty_label="Select your prefered time")
def __init__(self,*args,**kwargs):
city_id = kwargs.pop("city_id") # client is the parameter passed from views.py
super(ReservationForm, self).__init__(*args,**kwargs)
# TODO: move this to a manager
query = """SELECT ts.id, ts.datetime_to, ts.datetime_from, ts.available_reserves, l.name, l.'order'
FROM reservations_locationtimeslot AS ts
INNER JOIN reservations_location AS l ON l.id = ts.location_id
WHERE l.city_id = %s
AND ts.available_reserves > 0
AND ts.datetime_from > datetime() """
time_slots = LocationTimeSlot.objects.raw(query, [city_id])
self.fields['location_time_slot'].queryset = time_slots
The first error I get when trying to render the widget is: 'RawQuerySet' object has no attribute 'all'
I could solve that one thanks to one of the commets in enter link description here, by doing:
time_slots.all = time_slots.__iter__ # Dummy fix to allow default form rendering with raw SQL
But now I'm getting something similar when posting the form:
'RawQuerySet' object has no attribute 'get'
Is there a proper way to prepare a RawQuerySet to be used by ModelChoiceField?
Thanks!
Are you sure you actually need a raw query there? Just looking at that query, I can't see any reason you can't just do it with filter(location__city=city_id, available_reserves__gte=0, datetime_from__gt=datetime.datetime.now()).
Raw query sets are missing a number of methods that are defined on conventional query sets, so just dropping them in place isn't likely to work without writing your own definitions for all those methods.
I temporarily fixed the problem adding the missing methods.
The way I'm currently using the ModelChoiceField I only needed to add the all() and get() methods, but in different scenarios you might need to add some other methods as well. Also this is not a perfect solution because:
1) Defining the get method this way migth produce incorrect results. I think the get() method is used to validate that the selected option is within the options returned by all(). The way I temporarily implemented it only validates that the id exists in the table.
2) I guess the get method is less performant specified this way.
If anyone can think of a better solution, please let me know.
So my temporary solution:
class LocationTimeSlotManager(models.Manager):
def availableSlots(self, city_id):
query = """SELECT ts.id, ts.datetime_to, ts.datetime_from, ts.available_reserves, l.name, l.'order'
FROM reservations_locationtimeslot AS ts
.....
.....
MORE SQL """
time_slots = LocationTimeSlot.objects.raw(query, [city_id])
# Dummy fix to allow default form rendering with raw SQL
time_slots.all = time_slots.__iter__
time_slots.get = LocationTimeSlot.objects.get
return time_slots
I'm trying to work with m2m fields.
What I want to do is to have a string (CharField) where user can write the tags of a post, with each tag separated by commas.
I was able to do the creation in this way:
tags = tags.split(',')
for tag in tags:
obj, create = Tag.objects.get_or_create(name=tag)
pub.tags.add(obj)
Now, I want to do the UpdateView. Obviously if I don't specify the conversion from list to string in the form, I don't have any value set. So it should be something like:
for tag in tags:
str+=tag+","
The point is:
Do I have to write the conversion of list to string and string to list each time?
Can i specify somewhere how to do this conversion? Is there anything already implemented in Django?
PS: In the UpdateView, if I remove a tag, how can I remove it from the relation as well since I have to do the parsing by hand?
Thanks.
The simplest way is to remove all the tags from pub.tags first, then add them all back in:
# Clear the existing tags
pub.tags.clear()
tags = tags.split(',')
for tag in tags:
obj, create = Tag.objects.get_or_create(name=tag)
pub.tags.add(obj)
Instead of looping and building a String, you might try this more pythonic method:
tags = ['red', 'green', 'blue']
','.join(tags)
'red,green,blue'
I use django-tables2 to show some data in page,and now I want to make the cell link to some url,but the link url such as :
url(r'^(?P\w+)/(?P\d+)/$', 'pool.views.pooldatestock',
name="pool_date_stock"),
and I read the documents of django-tables2,but I can't find some excample about this problem.
the tables show in the page's url just like:http://127.0.0.1:8000/pool/20111222/
I try to write this in my tables.py :
class PoolTable(tables.Table):
number = tables.LinkColumn('pool.views.pooldatestock', args=[A('number')])
date = tables.Column()
and then I try to write:
class PoolTable(tables.Table):
number=tables.LinkColumn('pool.views.pooldatestock',
args=[A('date')],
kwargs=A('number')])
date = tables.Column()
but it's error too...
somebody can tell me how to solve this problem?or should I create my own table view, without django-tables.
Thanks.and Merry Christmas:)
It makes no sense for the kwargs parameter to be given a list, it should be given a dict. However as your URL doesn't used named groups, it doesn't need keyword arguments anyway. Just put both URL parameters in the args parameter:
class PoolTable(tables.Table):
number = tables.LinkColumn('pool.views.pooldatestock',
args=[A('date'), A('number')])
date = tables.Column()