Browse Source

Merge branch 'DTILegBG-master'

pull/886/head
LeandroRoberto 8 years ago
parent
commit
cc1fdefd07
  1. 6
      README.rst
  2. 6
      docs/instacao31.rst
  3. 7
      docs/logo_partidos.rst
  4. BIN
      docs/logo_partidos/dem.png
  5. BIN
      docs/logo_partidos/pdt.png
  6. BIN
      docs/logo_partidos/pfl.png
  7. BIN
      docs/logo_partidos/phs.png
  8. BIN
      docs/logo_partidos/pl.png
  9. BIN
      docs/logo_partidos/pmdb.png
  10. BIN
      docs/logo_partidos/pmn.png
  11. BIN
      docs/logo_partidos/pp.png
  12. BIN
      docs/logo_partidos/pps.png
  13. BIN
      docs/logo_partidos/prb.png
  14. BIN
      docs/logo_partidos/prona.png
  15. BIN
      docs/logo_partidos/prp.png
  16. BIN
      docs/logo_partidos/prtb.png
  17. BIN
      docs/logo_partidos/psb.png
  18. BIN
      docs/logo_partidos/psc.png
  19. BIN
      docs/logo_partidos/psdb.png
  20. BIN
      docs/logo_partidos/psdc.png
  21. BIN
      docs/logo_partidos/psl.png
  22. BIN
      docs/logo_partidos/psol.png
  23. BIN
      docs/logo_partidos/pt.png
  24. BIN
      docs/logo_partidos/ptb.png
  25. BIN
      docs/logo_partidos/ptc.png
  26. BIN
      docs/logo_partidos/ptdob.png
  27. BIN
      docs/logo_partidos/ptn.png
  28. BIN
      docs/logo_partidos/pv.png
  29. 5
      requirements/requirements.txt
  30. 3
      sapl/base/admin.py
  31. 44
      sapl/base/forms.py
  32. 38
      sapl/base/urls.py
  33. 2
      sapl/materia/tests/test_materia.py
  34. 16
      sapl/parlamentares/models.py
  35. 4
      sapl/sessao/forms.py
  36. 10
      sapl/sessao/views.py
  37. 2
      sapl/settings.py
  38. 13
      sapl/templates/base/login.html
  39. 1
      sapl/templates/base/nova_senha_form.html
  40. 14
      sapl/templates/base/recupera_senha_email_enviado.html
  41. 5
      sapl/templates/base/recuperar_senha_completo.html
  42. 13
      sapl/templates/base/recuperar_senha_email.html
  43. 1
      sapl/templates/base/recuperar_senha_email_form.html
  44. 3
      sapl/templates/parlamentares/layouts.yaml
  45. 10
      sapl/test_urls.py

6
README.rst

@ -49,6 +49,12 @@ Orientações gerais sobre o GitHub
Logo dos Partidos
===================================
`Logo dos Partidos <https://github.com/interlegis/sapl/blob/master/docs/logo_partidos.rst>`_
Issues Issues
------ ------

6
docs/instacao31.rst

@ -143,6 +143,9 @@ Criação da `SECRET_KEY <https://docs.djangoproject.com/es/1.9/ref/settings/#st
EMAIL_HOST = [Insira este parâmetro] EMAIL_HOST = [Insira este parâmetro]
EMAIL_HOST_USER = [Insira este parâmetro] EMAIL_HOST_USER = [Insira este parâmetro]
EMAIL_HOST_PASSWORD = [Insira este parâmetro] EMAIL_HOST_PASSWORD = [Insira este parâmetro]
DEFAULT_FROM_EMAIL = [Insira este parâmetro]
SERVER_EMAIL = [Insira este parâmetro]
* Uma configuração mínima para atender os procedimentos acima seria:: * Uma configuração mínima para atender os procedimentos acima seria::
@ -154,6 +157,9 @@ Criação da `SECRET_KEY <https://docs.djangoproject.com/es/1.9/ref/settings/#st
EMAIL_HOST = EMAIL_HOST =
EMAIL_HOST_USER = EMAIL_HOST_USER =
EMAIL_HOST_PASSWORD = EMAIL_HOST_PASSWORD =
DEFAULT_FROM_EMAIL =
SERVER_EMAIL =

7
docs/logo_partidos.rst

@ -0,0 +1,7 @@
========================
Logo Partidos Políticos
========================
Dentro da pasta docs/logo_partidos existem os logotipos dos Partidos Políticos em formato png, quem quiser pode usá-los no cadastro de partidos em tabelas auxiliares.

BIN
docs/logo_partidos/dem.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/logo_partidos/pdt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/logo_partidos/pfl.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/logo_partidos/phs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/logo_partidos/pl.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/logo_partidos/pmdb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
docs/logo_partidos/pmn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/logo_partidos/pp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/logo_partidos/pps.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
docs/logo_partidos/prb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
docs/logo_partidos/prona.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/logo_partidos/prp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/logo_partidos/prtb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/logo_partidos/psb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/logo_partidos/psc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/logo_partidos/psdb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/logo_partidos/psdc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/logo_partidos/psl.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/logo_partidos/psol.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/logo_partidos/pt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/logo_partidos/ptb.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
docs/logo_partidos/ptc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/logo_partidos/ptdob.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/logo_partidos/ptn.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/logo_partidos/pv.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

5
requirements/requirements.txt

@ -1,6 +1,9 @@
dj-database-url==0.4.1 dj-database-url==0.4.1
django>=1.9,<1.10 django>=1.9,<1.10
django-admin-bootstrapped==2.5.7 # TODO O django-admin-bootstrapped 2.5.7 não inseriu a mudança que permite
# a compatibilidade com Django 1.9+. A linha abaixo será mudada quando uma
# nova versão do django-admin-bootstrapped for lançada
git+git://github.com/django-admin-bootstrapped/django-admin-bootstrapped.git
django-bootstrap3==7.0.1 django-bootstrap3==7.0.1
django-bower==5.1.0 django-bower==5.1.0
django-braces==1.9.0 django-braces==1.9.0

3
sapl/base/admin.py

@ -8,6 +8,9 @@ register_all_models_in_admin(__name__)
admin.site.unregister(ProblemaMigracao) admin.site.unregister(ProblemaMigracao)
admin.site.site_title = 'Administração - SAPL'
admin.site.site_header = 'Administração - SAPL'
@admin.register(ProblemaMigracao) @admin.register(ProblemaMigracao)
class ProblemaMigracaoAdmin(admin.ModelAdmin): class ProblemaMigracaoAdmin(admin.ModelAdmin):

44
sapl/base/forms.py

@ -4,8 +4,9 @@ from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import (AuthenticationForm, PasswordResetForm,
from django.contrib.auth.models import Group SetPasswordForm)
from django.contrib.auth.models import Group, User
from django.contrib.auth.password_validation import validate_password from django.contrib.auth.password_validation import validate_password
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -695,3 +696,42 @@ class ConfiguracoesAppForm(ModelForm):
'texto_articulado_materia', 'texto_articulado_materia',
'texto_articulado_norma', 'texto_articulado_norma',
'proposicao_incorporacao_obrigatoria'] 'proposicao_incorporacao_obrigatoria']
class RecuperarSenhaForm(PasswordResetForm):
def __init__(self, *args, **kwargs):
row1 = to_row(
[('email', 12)])
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset(_('Insira o e-mail cadastrado com a sua conta'),
row1,
form_actions(save_label='Enviar'))
)
super(RecuperarSenhaForm, self).__init__(*args, **kwargs)
def clean(self):
email_existente = User.objects.filter(
email=self.data['email']).exists()
if not email_existente:
msg = 'Não existe nenhum usuário cadastrado com este e-mail.'
raise ValidationError(msg)
return self.cleaned_data
class NovaSenhaForm(SetPasswordForm):
def __init__(self, user, *args, **kwargs):
self.user = user
super(NovaSenhaForm, self).__init__(user, *args, **kwargs)
row1 = to_row(
[('new_password1', 6),
('new_password2', 6)])
self.helper = FormHelper()
self.helper.layout = Layout(
row1,
form_actions(save_label='Enviar'))

38
sapl/base/urls.py

@ -1,12 +1,17 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from django.contrib.auth import views from django.contrib.auth import views
from django.contrib.auth.views import (password_reset,
password_reset_done,
password_reset_confirm,
password_reset_complete)
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud
from .apps import AppConfig from .apps import AppConfig
from .forms import LoginForm from .forms import LoginForm, NovaSenhaForm, RecuperarSenhaForm
from sapl.settings import EMAIL_SEND_USER
from .views import (AppConfigCrud, CasaLegislativaCrud, HelpView, from .views import (AppConfigCrud, CasaLegislativaCrud, HelpView,
RelatorioAtasView, RelatorioHistoricoTramitacaoView, RelatorioAtasView, RelatorioHistoricoTramitacaoView,
RelatorioMateriasPorAnoAutorTipoView, RelatorioMateriasPorAnoAutorTipoView,
@ -16,6 +21,35 @@ from .views import (AppConfigCrud, CasaLegislativaCrud, HelpView,
app_name = AppConfig.name app_name = AppConfig.name
recuperar_senha = [
url(r'^recuperar-senha/email/$',
password_reset,
{'post_reset_redirect': 'sapl.base:recuperar_senha_finalizado',
'email_template_name': 'base/recuperar_senha_email.html',
'html_email_template_name': 'base/recuperar_senha_email.html',
'template_name': 'base/recuperar_senha_email_form.html',
'from_email': EMAIL_SEND_USER,
'password_reset_form': RecuperarSenhaForm},
name='recuperar_senha_email'),
url(r'^recuperar-senha/finalizado/$',
password_reset_done,
{'template_name': 'base/recupera_senha_email_enviado.html'},
name='recuperar_senha_finalizado'),
url(r'^recuperar-senha/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
password_reset_confirm,
{'post_reset_redirect': 'sapl.base:recuperar_senha_completo',
'template_name': 'base/nova_senha_form.html',
'set_password_form': NovaSenhaForm},
name='recuperar_senha_confirma'),
url(r'^recuperar-senha/completo/$',
password_reset_complete,
{'template_name': 'base/recuperar_senha_completo.html'},
name='recuperar_senha_completo'),
]
urlpatterns = [ urlpatterns = [
url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())),
@ -66,4 +100,4 @@ urlpatterns = [
name='login'), name='login'),
url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout'), url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout'),
] ] + recuperar_senha

2
sapl/materia/tests/test_materia.py

@ -159,6 +159,7 @@ def test_despacho_inicial_submit(admin_client):
comissao = mommy.make(Comissao, comissao = mommy.make(Comissao,
tipo=tipo_comissao, tipo=tipo_comissao,
nome='Teste', nome='Teste',
ativa=True,
sigla='T', sigla='T',
data_criacao='2016-03-18') data_criacao='2016-03-18')
@ -172,6 +173,7 @@ def test_despacho_inicial_submit(admin_client):
# Verifica se o despacho foi criado # Verifica se o despacho foi criado
despacho = DespachoInicial.objects.first() despacho = DespachoInicial.objects.first()
assert despacho.comissao == comissao assert despacho.comissao == comissao
assert despacho.materia == materia_principal assert despacho.materia == materia_principal

16
sapl/parlamentares/models.py

@ -86,7 +86,15 @@ class Coligacao(models.Model):
def __str__(self): def __str__(self):
return self.nome return self.nome
def get_logo_media_path(instance, subpath, filename):
return './sapl/partidos/%s/%s/%s' % (instance, subpath, filename)
def logo_upload_path(instance, filename):
return get_logo_media_path(instance, 'logo', filename)
class Partido(models.Model): class Partido(models.Model):
sigla = models.CharField(max_length=9, verbose_name=_('Sigla')) sigla = models.CharField(max_length=9, verbose_name=_('Sigla'))
nome = models.CharField(max_length=50, verbose_name=_('Nome')) nome = models.CharField(max_length=50, verbose_name=_('Nome'))
@ -94,6 +102,12 @@ class Partido(models.Model):
blank=True, null=True, verbose_name=_('Data Criação')) blank=True, null=True, verbose_name=_('Data Criação'))
data_extincao = models.DateField( data_extincao = models.DateField(
blank=True, null=True, verbose_name=_('Data Extinção')) blank=True, null=True, verbose_name=_('Data Extinção'))
logo_partido = models.ImageField(
blank=True,
null=True,
upload_to=logo_upload_path,
verbose_name=_('Logo Partido'),
validators=[restringe_tipos_de_arquivo_img])
class Meta: class Meta:
verbose_name = _('Partido') verbose_name = _('Partido')
@ -294,7 +308,7 @@ class Parlamentar(models.Model):
@property @property
def avatar_html(self): def avatar_html(self):
return '<img class="avatar-parlamentar" src='\ return '<img class="avatar-parlamentar" src='\
+ self.fotografia.url + '/>'if self.fotografia else '' + self.fotografia.url + '>'if self.fotografia else ''
class TipoDependente(models.Model): class TipoDependente(models.Model):

4
sapl/sessao/forms.py

@ -93,7 +93,7 @@ class ExpedienteMateriaForm(ModelForm):
return self.cleaned_data['numero_ordem'] return self.cleaned_data['numero_ordem']
def clean_data_ordem(self): def clean_data_ordem(self):
return datetime.now() return self.instance.sessao_plenaria.data_inicio
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
@ -136,7 +136,7 @@ class OrdemDiaForm(ExpedienteMateriaForm):
'numero_materia', 'ano_materia', 'tipo_votacao'] 'numero_materia', 'ano_materia', 'tipo_votacao']
def clean_data_ordem(self): def clean_data_ordem(self):
return datetime.now() return self.instance.sessao_plenaria.data_inicio
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data

10
sapl/sessao/views.py

@ -133,6 +133,11 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
class CreateView(MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = OrdemDiaForm form_class = OrdemDiaForm
def get_initial(self):
self.initial['data_ordem'] = SessaoPlenaria.objects.get(
pk=self.kwargs['pk']).data_inicio.strftime('%d/%m/%Y')
return self.initial
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:ordemdia_list', return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
@ -331,6 +336,11 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
class CreateView(MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = ExpedienteMateriaForm form_class = ExpedienteMateriaForm
def get_initial(self):
self.initial['data_ordem'] = SessaoPlenaria.objects.get(
pk=self.kwargs['pk']).data_inicio.strftime('%d/%m/%Y')
return self.initial
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:expedientemateria_list', return reverse('sapl.sessao:expedientemateria_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})

2
sapl/settings.py

@ -167,6 +167,8 @@ EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='') EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='')
EMAIL_USE_TLS = config('EMAIL_USE_TLS', cast=bool, default=True) EMAIL_USE_TLS = config('EMAIL_USE_TLS', cast=bool, default=True)
EMAIL_SEND_USER = config('EMAIL_SEND_USER', cast=str, default='') EMAIL_SEND_USER = config('EMAIL_SEND_USER', cast=str, default='')
DEFAULT_FROM_EMAIL = config('DEFAULT_FROM_EMAIL', cast=str, default='')
SERVER_EMAIL = config('SERVER_EMAIL', cast=str, default='')
MAX_DOC_UPLOAD_SIZE = 5 * 1024 * 1024 # 5MB MAX_DOC_UPLOAD_SIZE = 5 * 1024 * 1024 # 5MB
MAX_IMAGE_UPLOAD_SIZE = 2 * 1024 * 1024 # 2MB MAX_IMAGE_UPLOAD_SIZE = 2 * 1024 * 1024 # 2MB

13
sapl/templates/base/login.html

@ -18,7 +18,7 @@
<div class="col-md-4 col-md-offset-4"> <div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default"> <div class="login-panel panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">Entrar</h3> <h3 class="panel-title"><center>Entrar</center></h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form id="login-form" method="post" action="{% url 'sapl.base:login' %}"> <form id="login-form" method="post" action="{% url 'sapl.base:login' %}">
@ -32,18 +32,19 @@
{% endif %} {% endif %}
<tr> <tr>
<td><b>Usuário</b></td> <p><b><center>Usuário</center></b></p>
<td>{{ form.username }}</td> {{ form.username }}
</tr> </tr>
<tr> <tr>
<td><b>Senha</b></td> <p><b><center>Senha</center></b></p>
<td>{{ form.password }}</td> {{ form.password }}
</tr> </tr>
</table> </table>
</p> </p>
<h5><a href="{% url 'sapl.base:recuperar_senha_email' %}"><center>Esqueceu sua senha?</center></a></h6>
<p class="bs-component"> <p class="bs-component">
<center> <center>
<input class="btn btn-success btn-sm" type="submit" value="login" /> <input class="btn btn-lg btn-success btn-block" type="submit" value="login" />
</center> </center>
</p> </p>
<input type="hidden" name="next" value="{{ next }}" /> <input type="hidden" name="next" value="{{ next }}" />

1
sapl/templates/base/nova_senha_form.html

@ -0,0 +1 @@
{% extends "crud/form.html" %}

14
sapl/templates/base/recupera_senha_email_enviado.html

@ -0,0 +1,14 @@
{% extends "crud/detail.html" %}
{% load i18n crispy_forms_tags %}
{% block base_content %}
<div class="container">
{% csrf_token %}
<div class="row">
<p>Foi enviado um e-mail para o endereço inserido. Verifique-o e siga as instruções.</p>
<p>Caso não receba, procure-o na caixa de spam.</p>
</div>
</div>
{%endblock%}

5
sapl/templates/base/recuperar_senha_completo.html

@ -0,0 +1,5 @@
{% extends "crud/detail.html" %}
{% block table_content %}
A sua senha foi alterada com sucesso! Clique <a href="{% url 'sapl.base:login' %}">aqui</a> e faça seu login.
{% endblock %}

13
sapl/templates/base/recuperar_senha_email.html

@ -0,0 +1,13 @@
<p>Você está recebendo este e-mail pois solicitou recuperação de senha de sua conta no site <b>SAPL</b>.</p></br></p>
<p>Por favor clique no link a seguir e redefina sua senha:</p></br>
<p><a href="{{ protocol }}://{{ domain }}{% url 'sapl.base:recuperar_senha_confirma' uidb64=uid token=token %}">
Clique aqui</a></p></br>
<p>Caso não tenha solicitado a alteração de sua senha, favor ignorar este e-mail.</p></br>
<p>Atenciosamente,</p>
<p>A equipe <b>SAPL</b></p>

1
sapl/templates/base/recuperar_senha_email_form.html

@ -0,0 +1 @@
{% extends "crud/form.html" %}

3
sapl/templates/parlamentares/layouts.yaml

@ -13,7 +13,8 @@ Coligacao:
Partido: Partido:
{% trans 'Partido Político' %}: {% trans 'Partido Político' %}:
- nome:6 sigla data_criacao data_extincao - nome:6 data_criacao data_extincao
- logo_partido
Dependente: Dependente:
{% trans 'Dependentes' %}: {% trans 'Dependentes' %}:

10
sapl/test_urls.py

@ -145,6 +145,7 @@ def test_crudaux_list_do_crud_esta_na_pagina_sistema(url_item, admin_client):
Se encontra em %s.urls Se encontra em %s.urls
""" % (url, app_name) """ % (url, app_name)
apps_url_patterns_prefixs_and_users = { apps_url_patterns_prefixs_and_users = {
'api': { 'api': {
'prefixs': [ 'prefixs': [
@ -158,6 +159,7 @@ apps_url_patterns_prefixs_and_users = {
'/logout', '/logout',
'/ajuda', '/ajuda',
'/email', '/email',
'/recuperar-senha'
]}, ]},
'comissoes': { 'comissoes': {
'users': {'operador_geral': ['/sistema', '/comissao'], 'users': {'operador_geral': ['/sistema', '/comissao'],
@ -258,10 +260,10 @@ def test_urlpatterns(url_item, admin_client):
break break
assert isvalid, """ assert isvalid, """
O prefixo da url (%s) não está no padrão de sua app (%s). O prefixo da url (%s) não está no padrão de sua app (%s).
Os prefixos permitidos são: Os prefixos permitidos são:
%s %s
""" % (url, app_name, prefixs) """ % (url, app_name, prefixs)
urls_publicas_excecoes = { urls_publicas_excecoes = {

Loading…
Cancel
Save