Django endless pagination with a request.method == 'POST'? - ajax

I'm trying to get Django Endless pagination to work on a search form.
All the examples and tutorials I've seen online show how to do it with a simple .all() queryset, but I need to filter out by the search results that I've had in the POST.
Here's how my view looks like for now:
#page_template("core/search_box.html")
def search(request,template = "core/search.html",page_template = "core/search_box.html",extra_context = None):
if request.is_ajax():
#template=page_template()
#users = Skill_User.objects.filter(skill__name__icontains=content).order_by('-level')
#return render_to_response( template , {'page_template': page_template,'menu_home_active':True, 'form':search_form, 'result':users} , context_instance )
return HttpResponse("AJAX")
elif request.method == 'POST':
search_form = SearchForm( request.POST )
# If Form is Valid
if search_form.is_valid():
type = search_form.cleaned_data['type']
content = search_form.cleaned_data['content']
print 'CONTENT ' + str(content)
if (type == 'O'):
users = Skill_User.objects.filter(skill__name__icontains=content).order_by('-level')
elif (type == 'G'):
users= {}
return render_to_response( template , {'page_template': page_template,'menu_home_active':True, 'form':search_form, 'result':users} , context_instance=RequestContext(request) )
else:
return HttpResponse("NOT OK")
So the search is done on POST. But how can I pass this search POST thingy to the ajax query that's done by the endless-pagination plug-in ? I commented out everything in the request.ajax() part, I just need "users" to be filled by the same data as after the POST request. Basically, for now when I scroll down I have "AJAX" showing up, and I'd like the rest of my query as well.
Any ideas? I haven't found anything obvious online about that. I come from a PHP background, and I would think about $_SESSION[] variables. Is there something similar in Django?

Ok, it's doable with a simple request.session[""] object.

Related

Flask WTF validation False on first submit, True on second

I am using the following code in a Flask-wtforms. I have tried with and without various validators in the SelectField but on the first time the user submits the form validation returns false.
I have also tried removing the extra validate method but still leaving a validator in the SelectField and again validation returns False on first submit.
Essentially I want to know if the SelectField is not set to a value of -1 (ie has been populated by the view method and presumably user is happy with the currently active item). I am not sure why the form if valid on second submit even though nothing else has been selected on the form
forms.py
something = SelectField(label = 'Something', choices = [('-1','Select Something')], default=('-1','Select Something'), id='select_something', validators=[validators.DataRequired(message='Nothing selected')])
#NB the line below with no validator also prints "--validate() returned false"
#something = SelectField(label = 'Something', choices = [('-1','Select Something')], default=('-1','Select Something'), id='select_something')
submit = SubmitField('Submit')
def validate(self):
rv = Form.validate(self)
if not rv:
print("--validate() returned false")
return False
#the line below never fired, see fix in following line
#if self.something.data == -1:
if str(self.something.data) == '-1':
logger.debug("--validate() data==-1")
return False
return True
view.py
form = Something(request.form)
if request.method == 'GET':
#get tuple_list from database
...
form.something.choices = tuple_list
form.something.default = tuple_list[0]
if request.method == 'POST' and form.validate():
print('Something added.')
I was using string instead of integers for the first part of each choices tuple (ie should be (1, 'text')) and not setting default correctly (just set default = n where n = integer).
Note the form.process() call as found here: How do you set a default value for a WTForms SelectField?
Fixes below:
views.py
form = Something(request.form)
#get tuple_list from database
...
form.something.choices = tuple_list
form.something.default = tuple_list[0][0] #integer id value
form.process()
if request.method == 'POST' and form.validate():
return self.render_template('it_works.html')
return self.render_template('select_something.html')
forms.py
#no validator used here
something = SelectField(label = 'Something', choices = [], id='select_something')
submit = SubmitField('Submit')
def validate(self):
if len(self.something.choices) == 0:
return False
return True

Filtering models with pagination only filters first page - rails 3

I have a model which I am filtering based on some parameters given by the user. The filtering works just fine but once
I start using pagination, only the records from the first page are filtered and the others are ignored.
This is my code in the controller for filtering:
#start_date = params[:start_date]
#registers = Register.all.order("payment_date DESC").page(params[:page]).per(params[:all] ? nil : Kaminari.config.default_per_page)
#registers.delete_if { |r| !(r.payment_date <= #end_date && r.payment_date >= #start_date) if (#start_date.present? && #end_date.present?) }
And in the view I use <%= paginate #registers %> to paginate the list.
Like #Raffael mentioned in a comment above, I had to use #registers = #registers.where(..) instead of #registers.delete_if(..) because it "screws your page numbers up".

trying to select a User in a TextInput in ModelForm in Django - and it won't work

I'm trying to create a webapp in django 1.9 for task tracking and ordering. The different tasks are divided into spaces (like different projects). Now, I want to be able to choose what the task is assigned to in the CreateView.
The problem is, that I have a large number of users in my system, so I do not want to show a dropdown. Instead, I want to use a TextInput widget, to have the form check for the available options (this way I can also use typeahead on the client side).
This is the best I could come up with for the TaskCreate view:
class TaskCreate(LoginRequiredMixin, CreateView):
"""
a view for creating new tasks
"""
model = Task
fields = ['space', 'name', 'description', 'assigned_to', 'due_date']
template_name = "task_tracker/task_form.html"
success_url = reverse_lazy('tracker:my_open_task_list')
def get_context_data(self, **kwargs):
context = super(TaskCreate, self).get_context_data(**kwargs)
context['header_caption'] = 'Create'
context['submit_caption'] = 'Create'
context['all_usernames'] = [x.username for x in User.objects.all()]
return context
def get_form(self, form_class=None):
form = super(TaskCreate, self).get_form(form_class)
form.fields['assigned_to'].choices = [(x.username, x.id) for x in User.objects.all()]
form.fields['assigned_to'].initial = self.request.user.username,
form.fields['assigned_to'].widget = widgets.TextInput()
try:
form.fields['space'].initial = Space.objects.get(name=self.request.GET['space'])
finally:
return form
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.assigned_to = User.objects.get(username=form.cleaned_data['assigned_to'])
return super(TaskCreate, self).form_valid(form)
But the thing is that this is not working - the form still considers my choice to be illegal, even when I type in a valid username.
I tried to switch places the x.username and x.id in the choice field but it didn't help me.
I'm stuck on this for a week now. Can anybody help me please?

linqToTwitter UserID always zero

I need to construct the URL to the original tweet as
http://twitter.com/{twitter-user-id}/status/{tweet-staus-id}
Joe's code on linq2twitter works fine, but when I replace User.ScreenNameResponse from his sample with User.UserID,
the UserID is always zero. The debugger shows tweet.UserID is also zero. Most fields are populated.
My code:
var twitterCtx = new TwitterContext(getAuth());
var searchResponse =
await
(from search in twitterCtx.Search
where search.Type == SearchType.Search &&
search.Query == searchTxt &&
search.Count == searchCount
select search)
.SingleOrDefaultAsync();
if (searchResponse != null && searchResponse.Statuses != null)
searchResponse.Statuses.ForEach(tweet =>
Console.WriteLine(
"User: {0}, Tweet: {1}",
//tweet.User.ScreenNameResponse,
tweet.User.UserID,
tweet.Text));
Version: 3.1.1 from NuGet using app authentication.
How can I get the UserID so I can construct the tweet URL?
This SO thread (use id_str) did not help.
That would be in tweet.User.UserIDResponse.
A bit of background: Anything used as an input parameter is also looked at in the query response, so if a user omits the parameter in a query but the twitter response contains a value, it was being filtered out of the results. To fix this, I adopted a convention where any return parameters also match input parameters would have a 'Response' suffix. e.g. ScreenName (input) and ScreenNameResponse (output). To find which values are input, the docs for each API (including Search) call contain the input/filter parameters.

How to save a set of things over and over (autosave)

I am creating a set of things (each thing has FK to the set) directly with forms. The problem I am having is with the view(s).
I want to create the set for the things and then update all the things over and over using AJAX (Kind of like autosave). In my case the set is a SurveySet and the thing is a Survey.
def screen_many(request):
if not request.is_ajax():
# get an ordered QuerySet of students
students = ids_to_students(request.GET.items())
e_students = ids_to_students(request.GET.items(), 'e')
i_students = ids_to_students(request.GET.items(), 'i')
survey_count = len(students)
# Build a dataset of students with there associated behavior types.
data = [{'student':s.pk, 'behavior_type': 'E'} for s in e_students]
data += [{'student':s.pk, 'behavior_type': 'I'} for s in i_students]
# Use that dataset as initial data for a formset
SurveyFormset = formset_factory(SurveyForm, extra=0)
survey_formset = SurveyFormset(initial=data)
# ... not shown: customizing the crispy form helper
# Make a new survey set...
ss = SurveySet()
ss.user=request.user
ss.save()
if request.is_ajax():
surveyset = get_object_or_404(SurveySet, pk=ss.pk)
surveys = surveyset.survey_set.all()
survey_formset = SurveyFormset(request.POST, instance=surveyset)
if survey_formset.is_valid():
# Create surveys for this surveyset
for form in survey_formset.forms:
saved = form.save(commit=False)
saved.surveyset = ss
saved.save()
HttpResponse('saved.')
formsetWithStudents = zip(survey_formset.forms, students)
c = {
'formsetWithStudents' : formsetWithStudents,
'students' : students,
'survey_count' : survey_count,
'e_students': e_students,
'i_students': i_students,
'survey_formset': survey_formset,
}
c.update(csrf(request))
return render_to_response("reports/screen_many.html", c)
If my URL looks like this: http://127.0.0.1:8000/screen_many/?e_1=13&e_2=12&i_1=14 The view makes 3 survey sets all the while complaining that there is an
UnboundLocalError at /screen_many/
local variable 'ss' referenced before assignment
I feel like I need to make a separate view just for the ajax and I want the SurveySet object to only be created once.
So, in other words. I am filling in forms of a formset which update after clicking "view next form" This is in my template.
$('.next').click(function(){
$(this).parent().hide()
$(this).parent().next().show()
var posting = $.post('/screen_many/', $('form').serializeArray() );
posting.done(function(response){
console.log(response)
});
Or I could send the POST data here:
def save_as_you_go(request):
if request.is_ajax():
# Get the surveyset from POST
ss = request.POST['form-0-surveyset']
surveyset = get_object_or_404(SurveySet, pk=ss)
surveys = surveyset.survey_set.all()
SurveyFormSet = inlineformset_factory(SurveySet, Survey, form=SurveyForm, can_delete=False, extra=0)
survey_formset = SurveyFormSet(request.POST, instance=surveyset)
if survey_formset.is_valid():
for form in survey_formset.forms:
student = form.save(commit=False)
student.surveyset = surveyset
student.save()
return HttpResponse('saved.')
else:
return HttpResponseRedirect('/')
But then I get
[u'ManagementForm data is missing or has been tampered with']
Forgive me if my answer seems naive--I am new to Python and Django, but it looks like you are setting the ss variable in the non-ajax request and then referencing it in the ajax request. Perhaps you can set ss prior to the if statements?
#set ss variable before if statements
ss = SurveySet()
ss.user=request.user
ss.save()
if not request.is_ajax():
###do your non-ajax request stuff
if request.is_ajax():
###do your ajax request stuff

Resources