How to combine change_list_template in ModelAdmin mixin

2017-06-29 Thread ecas

I would like to create a mixin to extend the ModelAdmin class that adds a 
description text to the view, overriding the default change_list_template.

[admin_extra.py]
class DescriptionAdminMixin(object)
change_list_template = "description_change_list.html"
...

def changelist_view(self, request, extra_context=None):
extra_context = extra_context or {}
extra_context.update({
'description': self.description,
})
return super(DescriptionAdminMixin, self).changelist_view(request, 
extra_context=extra_context)

[description_change_list.html]
{% extends "admin/change_list.html" %}
{% block object-tools %}
{% block description %}
{% if description %}{{ description }}{% endif %}
{% endblock description %}
{{ block.super }}
{% endblock %}


This works fine if used on a ModelAdmin, but it fails if used on an already 
subclassed ModelAdmin that also defines change_list_template, as it gets 
overwritten.


Ex. adding django-import-export mixin:

class MyModelAdmin(DescriptionAdminMixin, ExportMixin, ModelAdmin): 
...

where ExportMixin is defined as:

class ExportMixin(ImportExportMixinBase):
...
change_list_template = 'admin/import_export/change_list_export.html'
...

Is there a preferred way to combine both templates?


The solution I use for now is defining a parent_template in the context, 
and use that in the template to extend from it

[admin_extra.py]
class DescriptionAdminMixin(object)
change_list_template = "description_change_list.
...
def changelist_view(self, request, extra_context=None):
# Define parent object template, or use the default admin change 
list template
opts = self.model._meta
app_label = opts.app_label
parent_template_list = super(DescriptionAdminMixin, 
self).change_list_template or [
'admin/%s/%s/change_list.html' % (app_label, opts.model_name),
'admin/%s/change_list.html' % app_label,
'admin/change_list.html'
]
parent_template = 
SimpleTemplateResponse(None).resolve_template(parent_template_list)

extra_context = extra_context or {}
extra_context.update({
'description': self.description,
'parent_template': parent_template,
})
return super(DescriptionAdminMixin, self).changelist_view(request, 
extra_context=extra_context)

[description_change_list.html]
{% extends parent_template %}
{% block object-tools %}
{% block description %}
{% if description %}{{ description }}{% endif %}
{% endblock description %}
{{ block.super }}
{% endblock %}

Is there any better solution? Is there a way for the AdminObject to provide 
the default template, something like get_change_list_template() to avoid 
doing the template resolution? Or even better some built-in way of getting 
the template of the parent class?



-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/62cb6134-cae1-48a0-8938-41604553d07f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Django tutorial - Misleading instructions

2017-06-30 Thread ecas
As Tim said, the APP_DIRS flag enables the app template loader.

https://docs.djangoproject.com/en/1.11/ref/templates/api/#django.template.loaders.app_directories.Loader

"Loads templates from Django apps on the filesystem. For each app in 
INSTALLED_APPS 
,
 
the loader looks for a templates subdirectory. If the directory exists, 
Django looks for templates in there."



El divendres, 30 juny de 2017 3:54:27 UTC+2, Justin Stubbs va escriure:
>
> Hi Guys,
>
> Im following the tutorial 
> https://docs.djangoproject.com/en/1.11/intro/tutorial03/ and have found 
> that the section on templates doesn't appear to be correct.
>
> The section talks about how django templates are loaded by default if you 
> put them in the correct path:
>
>
>
> 
>
>
>
> def auth(request):
> return render(request, 'g_auth/index.html')
>
>
>
>
> but when I used a similar example django complained about not being able 
> to find the templates. I ended up having to change the django settings file 
> 'DIRS':
>
> TEMPLATES = [
> {
> 'BACKEND': 'django.template.backends.django.DjangoTemplates',
> 'DIRS': [
> os.path.join(BASE_DIR, 'g_auth/templates')
> ],
> 'APP_DIRS': True,
> 'OPTIONS': {
> 'context_processors': [
> 'django.template.context_processors.debug',
> 'django.template.context_processors.request',
> 'django.contrib.auth.context_processors.auth',
> 'django.contrib.messages.context_processors.messages',
> ],
> },
> },
> ]
>
>
> After reading 
> https://docs.djangoproject.com/en/1.11/ref/templates/upgrading/
>
> Hoping to get this clarified as for a beginner this would be quite 
> complicated(assuming I haven't missed the boat completely here)
>
> Cheers,
>
> Justin
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/c7c7c964-b292-41b4-a61b-89761b85aa91%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How to create a fixed-length binary field with a unique constraint?

2017-07-11 Thread ecas
I would use:

fingerprint_sha256 = models.CharField(max_length=64, unique=True, 
db_index=True)

In hexadecimal, a SHA-256 uses 64 characters (4 bits per char).
The ASCII of the characters used in the hexadecimal representation are 1 
byte in UTF-8 (0-9, a-f).

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/b6734947-ecec-4983-9253-57f1d95f13f8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: how to display a foreign key image of an object in an object_list view/template?

2017-07-11 Thread ecas

You can query for the images, and keep the first one for the template 
rendering.

products = Product.objects.all()
for product in products:
products.image = product.productimages_set.first()




-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/ea2caaf4-7cdf-450d-973b-23fefc82018a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: how to display a foreign key image of an object in an object_list view/template?

2017-07-11 Thread ecas
There was a typo:

products = Product.objects.all()
for product in products:
product.image = product.productimages_set.first()


Other than that, it should work. You could try this in the django shell, 
just to verify the reverse name of the relationship.

from your_app.models import *
product=Product.objects.first()
product.productimages_set.first()

And debug from there.

El dimarts, 11 juliol de 2017 16:20:00 UTC+2, Bledi va escriure:
>
> Thanks, but I am getting this error:
>
> 'Product' object has no attribute 'productimages_set'
>
>
>
> On Tuesday, July 11, 2017 at 5:29:15 AM UTC-4, ecas wrote:
>>
>>
>> You can query for the images, and keep the first one for the template 
>> rendering.
>>
>> products = Product.objects.all()
>> for product in products:
>> products.image = product.productimages_set.first()
>>
>>
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/ef17071e-e27e-43ba-a012-729372af518e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Django Forms HorizontalRadioSelect Renderer not working.

2017-07-25 Thread ecas
Which version of Django are you using? From 1.11 the widgets changed to a 
template mechanism.

https://docs.djangoproject.com/en/1.11/ref/forms/widgets/#radioselect

Maybe this can help:
https://stackoverflow.com/questions/44187640/django-1-11-horizontal-choice-field

El dimarts, 25 juliol de 2017 9:53:13 UTC+2, Shazia Nusrat va escriure:
>
> Hi,
>
> I need to select form values horizontally but couldn't get it work.
>
> Following is the code:
>
> class HorizontalRadioRenderer(forms.RadioSelect.renderer):
>   def render(self):
> return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))
>
> class ResponseForm(models.ModelForm):
> class Meta:
> model = Response
> fields = ('interviewer', 'interviewee', 'conditions', 'comments')
> def __init__(self, *args, **kwargs):
> # expects a survey object to be passed in initially
> survey = kwargs.pop('survey')
> self.survey = survey
> super(ResponseForm, self).__init__(*args, **kwargs)
> self.uuid = random_uuid = uuid.uuid4().hex
> # add a field for each survey question, corresponding to the 
> question
> # type as appropriate.
> data = kwargs.get('data')
> for q in survey.questions():
> if q.question_type == Question.TEXT:
> self.fields["question_%d" % q.pk] = 
> forms.CharField(label=q.text,
> widget=forms.Textarea)
> elif q.question_type == Question.RADIO:
> question_choices = q.get_choices()
> self.fields["question_%d" % q.pk] = 
> forms.ChoiceField(label=q.text,
> 
> widget=forms.RadioSelect(renderer=HorizontalRadioRenderer),
> choices = question_choices)
>
> Error:
>
> class HorizontalRadioRenderer(forms.RadioSelect.renderer):
> AttributeError: type object 'RadioSelect' has no attribute 'renderer'
>
> Please advise
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/d7280ade-f0c0-4c31-813f-1747f1f3cd29%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How can I auto-fill a field in the model without showing a form field to the user?

2017-07-25 Thread ecas
One way could be to overload the save method of the model. Maybe something 
like this in your models.py:

import datetime

class Invoice(models.Model):

def save(self, *args, **kwargs):
if not self.id:
today = datetime.date.today()
date_str = datetime.datetime.strftime(today, '%y%m%d')
last_invoice = 
Invoice.objects.filter(invoice_number__startswith=date_str).order_by('invoice_number').last()
if last_invoice:
last_invoice_num = last_invoice.invoice_number[-2:]
new_invoice_num = int(last_invoice_num) + 1
new_invoice_num = "%02d" % new_invoice_num
else:
new_invoice_num = '01'
self.invoice_number = date_str + new_invoice_num
super(Invoice, self).save(*args, **kwargs)


El dimarts, 25 juliol de 2017 6:23:44 UTC+2, Alexander Joseph va escriure:
>
> I'm new to django, but coming from php I think its the greatest thing ever.
>
> I have a model for Invoices ...
>
> {{{
> from django.conf import settings
> from django.db import models
> from django.core.urlresolvers import reverse
> #from django.contrib.auth.models import User
>
> # Create your models here.
> class Invoice(models.Model):
> created_at = models.DateTimeField(auto_now_add=True)
> their_company = models.CharField(max_length=255)
> invoice_number = models.CharField(max_length=50, default='')
> bill_to = models.CharField(max_length=255, default='')
> created_by = models.ForeignKey(settings.AUTH_USER_MODEL)
> 
> class Meta:
> ordering = ['invoice_number', ]
> 
> def __str__(self):
> return self.invoice_number
> 
> def get_absolute_url(self):
> return reverse("accounting:invoices:detail", kwargs={"pk": self.pk
> })
> }}}
>
> right now the user has to put in the invoice number themselves. I want to 
> not give the user that option though - I'd like to autofill that field in 
> the database with a concatenation of the 2 digit year (17) plus 2 digit 
> month (07) plus 2 digit day (24) and then a 2 digit auto increment for 
> every invoice created on that specific date so the first invoice created 
> today would be 17072401 and the second would be 17072402, etc. I'm guessing 
> I need a field just for the date and another for the iteration of each 
> invoice.
>
> Can anyone give me some direction on this? First I'm not sure how to 
> autofill a field in the database without getting the input from the user, 
> and I'm also not sure how I would do the concatenation with the right 
> numbers. Thanks for your help
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/2628139c-e93e-474d-8d8e-d71c88e4d99c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.