I'm in the progress of creating a sitemap for my new site.
the site only contains static pages.
I'm trying to get this snippet working:
class StaticSitemap(sitemaps.Sitemap):
"""Return the static sitemap items"""
priority = 0.5
def __init__(self, patterns):
self.patterns = patterns
self._items = {}
self._initialize()
def _initialize(self):
for p in self.patterns:
if getattr(p, 'name', None) is not None:
print p.name
self._items[p.name] = self._get_modification_date(p)
def _get_modification_date(self, p):
template = getattr(p, 'template', None)
template_path = self._get_template_path(template)
mtime = os.stat(template_path).st_mtime
return datetime.datetime.fromtimestamp(mtime)
def _get_template_path(self, template_path):
for template_dir in settings.TEMPLATE_DIRS:
path = os.path.join(template_dir, template_path)
if os.path.exists(path):
return path
return None
def items(self):
return self._items.keys()
def changefreq(self, obj):
return 'monthly'
def lastmod(self, obj):
return self._items[obj]
def location(self, obj):
return reverse(obj)
and I'm getting this KeyError on template from this line: template = p.default_args['template']
How can I get template name?
got it working.
Just added template to kwargs of each url
Related
I use a CB ListView for displaying objects. I want to add a session variable based on another models' PK during the execution of my ListView:
views.py
class ProduitListView(LoginRequiredMixin, ListView):
model = Produit
context_object_name = "produits"
paginate_by = 10
template_name = 'products/produits.html'
ordering = ['-mageid', ]
def get_context_data(self, *args, **kwargs):
context = super(ProduitListView, self).get_context_data(
*args, **kwargs)
# used for incoming products (sourcing cf URLS)
supplier_pk = self.kwargs.get('pk', None)
if supplier_pk:
set_incoming_supplier(self.request, supplier_pk)
context['avail_warehouses'] = Warehouse.objects.all()
context['js_warehouses'] = serialize(
'json', Warehouse.objects.all(), fields=('code', 'id', ))
context['title'] = 'Produits'
return context
set_incoming_supplier (in another APP)
#login_required
def set_incoming_supplier(request, pk):
supplier = Supplier.objects.filter(pk=pk).first()
supp = SupplierSerializer(instance=supplier).data
rs = request.session
if 'income' in rs:
if 'cur_supplier' in rs['income']:
prev_supplier = rs['income']['cur_supplier']
if supp != prev_supplier:
return render(request, 'sourcing/alert_supplier_change.html',
{'prev_supplier': prev_supplier, 'cur_supplier': rs['income']['cur_supplier']})
rs['income'] = {'cur_supplier': supp}
I thought the return render(request, 'sourcing/alert_supplier_change... could "break" my ListView and render my alert page but it doesn't. ListView seems to continue and finally renders my ProduitListView page.
Why doesn't this work ?
Finally found a solution that consists in using get() method within my CBV. In it, I evaluate my supplier with set_incoming_supplier() that returns a context or None. According to this evaluation, I render either the regular template or my alert template.
ProduitListView(LoginRequiredMixin, ListView):
class ProduitListView(LoginRequiredMixin, ListView):
model = Produit
context_object_name = "produits"
paginate_by = 10
template_name = 'products/produits.html'
ordering = ['-mageid', ]
def get_context_data(self, *args, **kwargs):
context = super(ProduitListView, self).get_context_data(
*args, **kwargs)
context['avail_warehouses'] = Warehouse.objects.all()
context['js_warehouses'] = serialize(
'json', Warehouse.objects.all(), fields=('code', 'id', ))
context['title'] = 'Produits'
return context
def get(self, request, *args, **kwargs):
supplier_pk = self.kwargs.get('pk', None)
if supplier_pk:
context = set_incoming_supplier(self.request, supplier_pk)
if context:
return render(request, 'sourcing/alert_supplier_change.html', context)
return super().get(request, *args, **kwargs)
set_incoming_supplier()
def set_incoming_supplier(request, pk):
supplier = Supplier.objects.filter(pk=pk).first()
supp = SupplierSerializer(instance=supplier).data
rs = request.session
if 'income' in rs:
if 'cur_supplier' in rs['income']:
prev_supplier = rs['income']['cur_supplier']
if supp != prev_supplier:
return {'prev_supplier': prev_supplier, 'cur_supplier': supp}
rs['income'] = {'cur_supplier': supp}
Maybe not the best way but it works well.
After creating an object without template, I am trying to return to the same list view but it sends the reverse match error.
This is my code:
Function to create an object from other model:
def pieza_fast_create(request, id_reporte):
template_name = "metalitec/reportes_detalle.html"
context_object_name = "obj"
reporte = Reporte.objects.get(id=id_reporte)
pieza=Pieza.objects.create(reporte=reporte, descripcion="PIEZA 1")
piezas = Pieza.objects.all()
return render(request, template_name, {'id_reporte':id_reporte,'reporte':reporte, 'piezas':piezas})
Current View:
class ReporteDetalleView(LoginRequiredMixin, generic.TemplateView):
model = Reporte
template_name = "metalitec/reportes_detalle.html"
context_object_name = "obj"
#login_url = "bases:login"
def get(self, request, *args, **kwargs):
id_reporte = kwargs['id_reporte']
reporte = Reporte.objects.filter(id=id_reporte)
piezas = Pieza.objects.filter(reporte__id=id_reporte)
return render(request, self.template_name, {'id_reporte':id_reporte, 'reporte':reporte, 'piezas':piezas})
URLs:
path('reportes/piezas/fast/<int:id_reporte>',pieza_fast_create, name='pieza_new_fast'),
path('reportes/detalle/<int:id_reporte>',ReporteDetalleView.as_view(), name='reporte_detalle'),
Error:
Reverse for 'pieza_new_fast' with arguments '('',)' not found. 1 pattern(s) tried: ['metalitec/reportes/piezas/fast/(?P<id_reporte>[0-9]+)$']
Rather than rendering the template metalitec/reportes_detalle.html again, it is better to redirect to that view ReporteDetalleView. You can try like this:
from django.shortcuts import redirect
def pieza_fast_create(request, id_reporte):
reporte = Reporte.objects.get(id=id_reporte)
pieza=Pieza.objects.create(reporte=reporte, descripcion="PIEZA 1")
return redirect('reporte_detalle', id_reporte=id_reporte)
Also, you can add some improvements to your code like this:
class ReporteDetalleView(LoginRequiredMixin, generic.TemplateView):
model = Reporte
template_name = "metalitec/reportes_detalle.html"
slug_url_kwarg = "id_reporte"
context_object_name = "reporte"
def get_context_data(self, **kwargs):
context = super(ReporteDetalleView, self).get_context_data(**kwargs)
reporte = context["reporte"]
context["piezas"] = Pieza.objects.filter(reporte=reporte)
context["id_reporte"] = self.kwargs["id_reporte"]
return context
Here all My codes and I haven't set it yet, just a regular auth
class login(View):
template_name = "admin/page.html"
context = {}
def get(self, *args, **kwargs):
next = self.request.GET.get('next')
forms = adminForm()
if next :
self.context['next'] = next
self.context['forms'] = forms
return render(self.request, self.template_name, self.context)
def post(self, *args, **kwargs):
forms = adminForm(self.request.POST or None)
next = self.request.POST.get('next')
if forms.is_valid() :
user = authenticate(username=forms.cleaned_data.get('username'), password=forms.cleaned_data.get('password'))
login(self.request, user)# authenticate(username=forms.cleaned_data.get('username'), password=forms.cleaned_data.get('password')))
if next :
return redirect(next)
return redirect('/admin/users')
if not forms.is_valid() :
self.context['errors'] = 'Invalid Username or Password'
self.context['forms'] = forms
return render(request, self.template_name, self.context)
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
i am using class based generic view in my Subject_En roll application
my view.py is
cc = 0
#login_required
def add_subject_enroll(request):
user = request.user
obj = StudentRegistration.objects.get(user=user)
print "obj.first_name",obj.first_name
first_name = obj.first_name
print "first_name",first_name
if obj.user:
print "object exist"
#form = Subject_EnrollForm(request.POST or None, initial={'student_name' : first_name})
#form = Subject_EnrollForm( initial={'student_name' : obj.first_name})
form = Subject_EnrollForm(request.POST or None, request.FILES or None)
form.fields["student_name"].initial = first_name
form.fields["birth_place"].initial = obj.birth_place
form.fields["gender"].initial = obj.gender
form.fields["phone"].initial = obj.phone
form.fields["email"].initial = obj.email
form.fields["phone"].initial = obj.phone
form.fields["nationality"].initial = obj.nationality
form.fields["religion"].initial = obj.religion
form.fields["blood_group"].initial = obj.blood_group
form.fields["nationality"].initial = obj.nationality
form.fields["nationality"].initial = obj.nationality
form.fields["nationality"].initial = obj.nationality
form.fields["nationality"].initial = obj.nationality
else:
print "object not found"
Subject_EnrollForm(request.POST or None, request.FILES or None)
if request.POST:
if form.is_valid():
a = form.save()
a.user = request.user
a.save()
#user.save()
messages.add_message(request,messages.SUCCESS, "your Profile was added")
#return HttpResponseRedirect('/app/all')
return HttpResponseRedirect('/')
args = {}
args.update(csrf(request))
args['form'] = form
context = RequestContext(request,
{'request': request,
'user': request.user,
'form': form})
return render_to_response('subject_enroll/add_subject_enroll.html', args, context)
class Subject_EnrollListView(ListView):
"""View to display all published and visible news entries."""
template_name = "subject_enroll/subject_enroll_list.html"
def get_queryset(self):
return Subject_Enroll.objects.all()
class DetailViewMixin(object):
"""Mixin to handle different DetailView variations."""
model = Subject_Enroll
#slug_field = 'translations__slug'
def get_queryset(self):
#return Subject_Enroll.objects.all()
return Subject_Enroll.objects.lang(self.request, False)
class Subject_EnrollDetailView(DetailViewMixin, DetailView):
def get_context_data(self, **kwargs):
context = super(Subject_EnrollDetailView, self).get_context_data(**kwargs)
context['subject_enrolls'] = Subject_Enroll.objects.all()
return context
class Subject_EnrollUpdateView(UpdateView):
form_class = Subject_EnrollForm
model = Subject_Enroll
template_name = 'subject_enroll/subject_enroll_detail.html'
def get(self, request, **kwargs):
self.object = Subject_Enroll.objects.get(id=self.request.id)
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(object=self.object, form=form)
return self.render_to_response(context)
def get_object(self, queryset=None):
obj = Subject_Enroll.objects.get(id=self.kwargs['id'])
return obj
i try with pass form in context of Detilviewmixin
class DetailViewMixin(object):
"""Mixin to handle different DetailView variations."""
model = Subject_Enroll
#slug_field = 'translations__slug'
def get_context_data(self, **kwargs):
context = super(DetailViewMixin, self).get_context_data(**kwargs)
#context['form'] = Subject_EnrollForm
#context['form'] = Subject_EnrollForm()
return context
def get_queryset(self):
#return Subject_Enroll.objects.all()
return Subject_Enroll.objects.lang(self.request, False)
in that form are render on template but when i press save button so it can't save record
from this code i get all field access in "subject_enroll/subject_enroll_detail.html" like {{ object.student_name }}
{{ object.enroll_status }}
so it gives value of that field but now i want to edit record in subject_enroll_detail.html template like s
subject_enroll values "draft" to "submit" with click on some buttons in subject_enroll_detail.html template
i tried with form view and updateview but can't find solution
pls help!!!
Thanks in advance!!
from django.views.generic import UpdateView
class StudentRegistrationUpdateView(UpdateView):
model = StudentRegistration
form_class = Subject_EnrollForm #don't need if you are editing all the fields
template_name = 'subject_enroll/add_subject_enroll.html'
https://docs.djangoproject.com/en/1.7/ref/class-based-views/generic-editing/#updateview
in your urls.py
import StudentRegistrationUpdateView
in urls.py don't forget to include 'pk' like below, this determines which object to be updated
url(r'student/(?P<pk>\d+)/update/$', StudentRegistrationUpdateView.as_view(), name='student_registration_update'),