Attempting to get the most recent object in a query set and I keep getting error
TypeError at / 'PostManager' object is not iterable
How do you do this without iterating?
class DashboardTemplateView(TemplateView):
template_name = "base.html"
context_object_name = 'name'
def get_context_data(self, *args, **kwargs):
context = super(DashboardTemplateView,self).get_context_data(*args, **kwargs)
context["title"] = "This is about us"
return context
class MyView(ContextMixin, TemplateResponseMixin, View):
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
# mission_statement = Content.objects.filter(Content.objects.title == 'test')
# context = {'mission_statement' : mission_statement,
# 'content_list' : Content.objects.all(),
# 'post_list' : Post.objects.all()}
# context = {'content_list' : Content.objects.all(), 'post_list' : Post.objects.all()}
home_list = list(Post.objects).order_by('-id')[0]
context = {'content_list' : Content.objects.all(), 'home_list' : home_list.objects.all()}
return self.render_to_response(context)
This line is wrong:
home_list = list(Post.objects).order_by('-id')[0]
Post.objects is the PostManager : it is not a iterable, you cannot list() it.
I guess what you are after is this:
home_list = Post.objects.all().order_by('-id').first()
The difference between first() and [0] is that first() won't throw IndexError if no result in query set, it will return None.
A small paranthesis error on line below
home_list = list(Post.objects).order_by('-id')[0]
Change this to
home_list = list(Post.objects.all().order_by('-id'))[0]
An alternative one
home_list = Post.objects.all().order_by('-id').first()
Also calling objects method on home_list is not needed. Below would also work fine
context = {'content_list' : Content.objects.all(), 'home_list' : home_list}
Related
Hi in my code(not written by me) i have django form class and views class. I dont know how this is connected each other. Can anyone tell me how this is connected? Also can any one please tell me how this messege : Credential is in use by {0} collections that are turned on and "
"{1} collections that are turned off. Be mindful that over-using " "credentials may result in collecting being rate limited by the " "social media API is displayed, i mean if i need to change the alignment of this text where i should change?
My code classes are :
from forms.py :
class CollectionTwitterSearch2Form(BaseCollectionForm):
incremental = forms.BooleanField(initial=True, required=False, label=INCREMENTAL_LABEL, help_text=INCREMENTAL_HELP)
def __init__(self, *args, **kwargs):
super(CollectionTwitterSearch2Form, self).__init__(*args, **kwargs)
self.helper.layout[0][5].extend(('incremental',))
if self.instance and self.instance.harvest_options:
harvest_options = json.loads(self.instance.harvest_options)
if "incremental" in harvest_options:
self.fields['incremental'].initial = harvest_options["incremental"]
def save(self, commit=True):
m = super(CollectionTwitterSearch2Form, self).save(commit=False)
m.harvest_type = Collection.TWITTER_SEARCH_2
harvest_options = {
"incremental": self.cleaned_data["incremental"],
}
m.harvest_options = json.dumps(harvest_options, sort_keys=True)
m.save()
return m
from views.py :
def _get_credential_use_map(credentials, harvest_type):
credential_use_map = {}
if harvest_type in Collection.RATE_LIMITED_HARVEST_TYPES:
for credential in credentials:
active_collections = 0
inactive_collections = 0
for collection in credential.collections.all():
if collection.is_on:
active_collections += 1
else:
inactive_collections += 1
if active_collections == 0 and inactive_collections == 0:
credential_use_map[credential.id] = ("", "")
else:
credential_use_map[credential.id] = ("warning",
"Credential is in use by {0} collections that are turned on and "
"{1} collections that are turned off. Be mindful that over-using "
"credentials may result in collecting being rate limited by the "
"social media API.".format(active_collections,
inactive_collections))
return credential_use_map
class CollectionCreateView(LoginRequiredMixin, CollectionSetOrSuperuserPermissionMixin, SuccessMessageMixin,
CreateView):
model = Collection
template_name = 'ui/collection_create.html'
def get_initial(self):
initial = super(CollectionCreateView, self).get_initial()
initial["collection_set"] = CollectionSet.objects.get(pk=self.kwargs["collection_set_pk"])
return initial
def get_context_data(self, **kwargs):
context = super(CollectionCreateView, self).get_context_data(**kwargs)
context["collection_set"] = CollectionSet.objects.get(pk=self.kwargs["collection_set_pk"])
harvest_type = self.kwargs["harvest_type"]
context["harvest_type_name"] = _get_harvest_type_name(harvest_type)
credentials = _get_credential_list(self.kwargs["collection_set_pk"], harvest_type)
context["credentials"] = credentials
context["credential_use_map"] = _get_credential_use_map(credentials, harvest_type)
context["platform"] = Collection.HARVEST_TYPES_TO_PLATFORM[self.kwargs["harvest_type"]]
return context
def get_form_kwargs(self):
kwargs = super(CollectionCreateView, self).get_form_kwargs()
kwargs["coll"] = self.kwargs["collection_set_pk"]
kwargs['credential_list'] = _get_credential_list(self.kwargs["collection_set_pk"], self.kwargs["harvest_type"])
return kwargs
def get_form_class(self):
return getattr(forms, _get_collection_form_class(self.kwargs["harvest_type"]))
def get_success_url(self):
return reverse('collection_detail', args=(self.object.pk,))
def get_success_message(self, cleaned_data):
if self.object.required_seed_count() != 0:
return "New collection added. You can now add seeds."
return "New collection added."
Full code is here in this git : https://github.com/gwu-libraries/sfm-ui/tree/master/sfm/ui
It would be great anyone can explain how these two classes and template is connected and how the messege is displayed
The CollectionCreateView class is conected to the Form using the function get_form_class, this function is called by default by the CreateView, in there you can see is calling _get_collection_form_class() and as an argument is passing self.kwargs['harvest_type'] this kwargs is comming from the url declaration. The _get_collection_form_class function is returning the CollectionTwitterSearch2Form when the harvest_type is something like TwitterSearch2. The template is given by the template_name = 'ui/collection_create.html' again this is the default vehaviour. And finally for the message this is using SuccessMessageMixin.
Im trying to add a payment method.
I also add Getway and Get Success Message.
Now I want to show success message with cid and name in my template page.
When I want to get context data, I got This Error.
** Local variable 'cid' referenced before assignment. **
My code:
class CheckoutSuccessView(View):
model = Transaction
template_name = 'success.html'
def get(self, request, *args, **kwargs):
# return render(request, self.template_name,{'transaction':transaction})
return HttpResponse('nothing to see')
def post(self, request, *args, **kwargs):
data = self.request.POST
try:
Transaction.objects.create(
name = data['value_a'],
cid = data['value_b'],
tran_id=data['tran_id'],
val_id=data['val_id'],
amount=data['amount'],
card_type=data['card_type'],
card_no=data['card_no'],
...
...
)
messages.success(request,'Payment Successfull')
name = data['value_a'],
cid = data['value_b'],
except:
messages.success(request,'Something Went Wrong')
context = {
'cid': cid,
'name' : name
}
return render(request, 'success.html', context)
You may miss block or put extra indentation.
Define it before try block.
You may try this:
class CheckoutSuccessView(View):
model = Transaction
template_name = 'success.html'
def get(self, request, *args, **kwargs):
# return render(request, self.template_name,{'transaction':transaction})
return HttpResponse('nothing to see')
def post(self, request, *args, **kwargs):
data = self.request.POST
name = data['value_a'],
cid = data['value_b'],
try:
Transaction.objects.create(
name = data['value_a'],
cid = data['value_b'],
tran_id=data['tran_id'],
val_id=data['val_id'],
amount=data['amount'],
card_type=data['card_type'],
card_no=data['card_no'],
...
...
)
messages.success(request,'Payment Successfull')
except:
messages.success(request,'Something Went Wrong')
context = {
'cid': cid,
'name' : name
}
return render(request, 'success.html', context)
I think you are using sslcommerz-lib for SSLCOMMERZ PAYMENT GATEWAY.
In my Django Project I have the following Problem:
I would like to have a dynamic Django form. In the first step the user is asked something by the first form. When I get the postmethod the variables should be used for genereating a new form
my views.py
def calc(request):
if request.method =="POST":
get_form = CalculationForm(request.POST)
if get_form.is_valid():
op = get_form.cleaned_data['op']
ab = get_form.cleaned_data['ab']
alternative = AlternativForm(optype = op, wsgroup = ab)
return render(request, 'calculated_lensar.html', {"alternativ" : alternativ})
else:
form = CalculationForm()
return render(request, 'calc.html', {'form': form})
The secondform (postmethod) looks like
class AlternativForm(forms.Form):
praep_button = ((3, 'hallo'), (4, 'tschüss'))
def __init__(self, optype, wsgroup, *args, **kwargs):
super(AlternativForm, self).__init__(*args, **kwargs) #dont know for what this is standing
self.optype = optype
self.wsgroup = wsgroup
self.values = self.read_db()
self.praep_button = self.buttons()
self.felder = self.blub()
self.neu2 = self.myfield_choices()
def read_db(self):
import sqlite3
....
return result #tuple with 15x5 elements
def buttons(self):
praep_button = []
for i in self.values:
praep_button.append((i[4], i[1]))
return praep_button #Just formating result from read_db in tuple(15x2)
def blub(self):
return forms.ChoiceField(widget=forms.RadioSelect, choices=self.praep_button)
myfield = forms.ChoiceField(widget=forms.RadioSelect, choices=praep_button) #print --><django.forms.fields.ChoiceField object at 0x751f9b90>
def myfield_choices(self):
field = self['myfield']
"""i think here is the problem.
Above 'myfield' is a django.forms.fields.ChoiceField object, but here it is rendered to html (like it should be). I have the code from https://stackoverflow.com/questions/6766994/in-a-django-form-how-do-i-render-a-radio-button-so-that-the-choices-are-separat.
But instead i should use field = self.felder (radioselect woth tuple of the db)"""
widget = field.field.widget
attrs = {}
auto_id = field.auto_id
if auto_id and 'id' not in widget.attrs:
attrs['id'] = auto_id
name = field.html_name
return widget.render(name, field.value(), attrs=attrs)
#return widget.get_renderer(name, field.value(), attrs=attrs)
So all in all I hope the problem is clear.
If i am using AlternativForm() i get the constant form. Instead i would like to get a dynamic form. If I access in views.py:
alternative = AlternativForm(optype = op, wsgroup = ab)
alternative = alternativ.felder
than I get . Can I render that to html?
If I set in forms.py:
field = self.felder
than I get the error that it is a field and not a widget
Thank you for reading!
You just need to assign the choices in the form's __init__() method. Almost what you're doing, but instead of defining self.felder to be a field, you need to use the already initialised form's fields:
myfield = forms.ChoiceField(widget=forms.RadioSelect, choices=praep_button)
def __init__(self, optype, wsgroup, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['myfield'].choices = self.get_choices(optype, wsgroup) # create your choices in this method
def get_choices(optype, wsgroup):
# call your other methods here
return praep_button
According to this post, I'm trying to modify my whole script in order to get Class Based Views (CBV) in my Django application.
I would like to get any help, because it's the first time I'm using CBV.
My previous script function looks like this :
#login_required
def IdentityIndividuForm(request) :
success = False
query_Nom_ID = query_Prenom_ID = query_VilleNaissance_ID = None
if 'recherche' in request.GET:
query_Nom_ID = request.GET.get('q1NomID')
query_Prenom_ID = request.GET.get('q1PrenomID')
query_VilleNaissance_ID = request.GET.get('q1VilleNaissanceID')
sort_params = {}
lib.Individu_Recherche.set_if_not_none(sort_params, 'Nom__icontains', query_Nom_ID)
lib.Individu_Recherche.set_if_not_none(sort_params, 'Prenom__icontains', query_Prenom_ID)
lib.Individu_Recherche.set_if_not_none(sort_params, 'VilleNaissance__icontains', query_VilleNaissance_ID)
query_ID_list = Individu.objects.filter(**sort_params)
else :
query_ID_list = Individu.objects.none()
if request.method == 'POST':
form = IndividuFormulaire(request.POST or None, request.FILES or None)
if form.is_valid() :
post = form.save()
return HttpResponseRedirect(reverse('IndividuResume', kwargs={'id': post.id}))
else :
form = IndividuFormulaire()
form.fields['Utilisateur'].initial = request.user.last_name + " " + request.user.first_name
context = {
"form" : form,
"Individu" : Individu,
"query_Nom_ID" : query_Nom_ID,
"query_Prenom_ID" : query_Prenom_ID,
"query_VilleNaissance_ID" : query_VilleNaissance_ID,
"query_ID_list" : query_ID_list,
}
return render(request, 'Identity_Individu_Form.html', context)
I had a GET part and a POST part in my function but both part are independent. The first one lets to make a research over my database. The second one lets to create an object to my database.
My question is : How I can overwrite the GET part with function based on CBV ?
My new function form_valid(self, form) works well, but I don't overcome to migrate the GET part to my CBV part.
Thank you!
You can try it, first get super context data, after it do processing as you wish and after it update the contest data with yours
by default CreateView is subclass of the ProcessFormView that provide get method, as:
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
return self.render_to_response(self.get_context_data(form=form))
so you can try to override the get method with return as:
return self.render_to_response(self.get_context_data(request, form=form))
and the get_context_data
def get_context_data(self, **kwargs) :
context_data = super(IdentityIndividuFormView, self).get_context_data(**kwargs)
if 'recherche' in self.request.GET:
query_Nom_ID = self.request.GET.get('q1NomID')
query_Prenom_ID = self.request.GET.get('q1PrenomID')
query_VilleNaissance_ID = self.request.GET.get('q1VilleNaissanceID')
sort_params = {}
lib.Individu_Recherche.set_if_not_none(sort_params, 'Nom__icontains', query_Nom_ID)
lib.Individu_Recherche.set_if_not_none(sort_params, 'Prenom__icontains', query_Prenom_ID)
lib.Individu_Recherche.set_if_not_none(sort_params, 'VilleNaissance__icontains', query_VilleNaissance_ID)
query_ID_list = Individu.objects.filter(**sort_params)
context_data['queryset'] = query_ID_list
else :
query_ID_list = Individu.objects.none()
context_data['queryset'] = query_ID_list
return context_data
I see another issue here, that you missed out #login_required part of the check here, to do so use the mixin like this :
from django.contrib.auth.mixins import LoginRequiredMixin
class IdentityIndividuFormView(LoginRequiredMixin, CreateView) :
And I suppose in case of GET request you can update the context using this:
def get(self, request, *args, **kwargs):
I want to pass variable appuser to template and I don't understand how to do it.
I have tried to use kwargs.update but it still doesn't work.
I have a view:
class CausesView(AjaxFormView):
appuser = None
causes = []
cause_allocation_set = None
def prepare_request(self, request, *args, **kwargs):
self.causes = Cause.objects.filter(is_main_cause = True)
self.appuser = AppUser.get_login_user(request)
self.cause_allocation_set = set([r.cause_id for r in self.appuser.current_cause_save_point.cause_allocations_list])
def prepare_context(self, request, context, initial):
initial.update(
causes = self.cause_allocation_set,
appuser = self.appuser,
)
def prepare_form(self, request, form):
form._set_choices("causes", [(r.id, r.title) for r in self.causes])
def custom_context_data(self, request, **kwargs):
kwargs.update(
special_test = "dsf"
)
return kwargs
def process_form(self, request, form):
data = form.cleaned_data
try:
with transaction.atomic():
if self.cause_allocation_set != set(data.get('causes')):
self.appuser.save_causes(data.get('causes'))
except Exception as e:
message = "There was an error with saving the data: " + str(e.args)
return AjaxErrorResponse({'title':"Error", 'message':message})
return AjaxSuccessResponse('Causes Saved')
And I have a form:
class CauseForm(AjaxForm):
causes = forms.TypedMultipleChoiceField(label="Select Causes", choices = (), required = False, coerce = int,
widget = forms.CheckboxSelectMultiple())
def clean(self):
cleaned_data = super(CauseForm, self).clean()
causes = cleaned_data.get('causes')
validation_errors = []
if not causes is None and not len(causes):
validation_errors.append(forms.ValidationError("At least one Cause is required"))
if len(validation_errors):
raise forms.ValidationError(validation_errors)
return cleaned_data
How can I get variable appuser in temlpate?
For example:
{{ appuser.name }}
doesn't work.
Read How to use get_context_data in django
and
https://docs.djangoproject.com/en/1.9/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_context_data
Here is example of how you can do this
class CausesView(AjaxFormView):
...
def get_context_data(self, **kwargs):
context_data = super(CausesView, self).get_context_data(**kwargs)
context_data['appuser'] = self.appuser
return context_data