Como fazer uma instância de modelo somente leitura após salvá-lo uma vez?

votos
3

Uma das funcionalidades em um projeto Django Eu estou escrevendo está enviando uma newsletter. Eu tenho um modelo, Newslettere uma função, send_newsletterque tenho registrado para ouvir Newsletter's post_savesinal. Quando o objeto boletim é salvo através da interface de administração, send_newsletterverifica se createdé verdade, e se sim, na verdade, envia o e-mail.

No entanto, não faz muito sentido para editar um boletim informativo que já foi enviada, pelas razões óbvias. Existe uma maneira de fazer o Newsletterobjeto somente leitura uma vez que foi salvo?

Editar:

Eu sei que pode substituir o savemétodo do objeto para levantar um erro ou fazer nada se o objeto existia. No entanto, eu não vejo o ponto de fazer isso. Quanto ao primeiro, eu não sei onde pegar esse erro e como comunicar o usuário o fato de que o objeto não foi salvo. Quanto a este último dando a falsa feedback do usuário (interface de administração dizendo que o save sucedido), não parece ser uma coisa boa.

O que eu realmente quero é permitir que o usuário utilize a interface de administração para escrever o boletim e enviá-lo, e depois procurar os boletins que já foram enviados. Eu gostaria que a interface de administração para mostrar os dados de boletins enviados em uma caixa de entrada não editável, sem o botão Save. Alternativamente gostaria que o botão Save para ser inativo.

Publicado 21/01/2009 em 18:11
fonte usuário
Em outras línguas...                            


4 respostas

votos
7

Você pode verificar se é criação ou atualização no modelo do savemétodo:

def save(self, *args, **kwargs):
    if self.pk:
        raise StandardError('Can\'t modify bla bla bla.')
    super(Payment, self).save(*args, **kwargs)

Código acima irá gerar uma exceção se você tentar salvar um objeto existente. Objetos não previamente persistiu não têm suas chaves primárias definido.

Respondeu 21/01/2009 em 20:29
fonte usuário

votos
1

Sugestão de leitura: O Zen de Administrador no capítulo 17 do Livro Django .

Resumo: O administrador não é projetado para o que você está tentando fazer :(

No entanto, a versão 1.0 do livro cobre apenas Django 0,96, e as coisas boas têm acontecido desde então.

No Django 1.0, o site de administração é mais personalizável. Desde que eu não tenha personalizado administrador mim, eu vou ter que adivinhar com base nos documentos, mas eu diria que substituindo o modelo de formulário é a sua melhor aposta.

Respondeu 10/02/2009 em 09:57
fonte usuário

votos
0

O que você pode fazer facilmente, está fazendo todos os campos de somente leitura:

class MyModelAdmin(ModelAdmin):
    form = ...
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return MyModelAdmin.form.Meta.fields
        else: # This is an addition
            return []

Como para fazer o Salvar desaparecer, seria muito mais fácil se

  1. has_change_permission retornando False não iria desativar até mesmo exibir o formulário
  2. o trecho de código responsável por processar os controles de formulário admin (o admin_modify.submit_rowtemplatetag), não iria usar show_save=Trueincondicionalmente.

De qualquer forma, uma maneira de fazer essa cara não a ser prestado:

  1. Criar uma versão alternativa de has_change_permission, com lógica própria:

    class NoSaveModelAdminMixin(object):
        def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
            response = super(NoSaveModelAdmin, self).render_change_form(request, context, add, change,form_url, obj)
            response.context_data["has_change_permission"] = self.has_real_change_permission(request, obj)
        def has_real_change_permission(self, request, obj):
            return obj==None
        def change_view(self, request, object_id, extra_context=None):
            obj = self.get_object(request, unquote(object_id))
            if not self.has_real_change_permission(request, obj) and request.method == 'POST':
                raise PermissionDenied 
            return super(NoSaveModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
    
  2. Substituir o templatetag submit_row semelhante a este:

    @admin_modify.register.inclusion_tag('admin/submit_line.html', takes_context=True)
    def submit_row(context):
        ...
            'show_save': context['has_change_permission']
        ...
    
    admin_modify.submit_row = submit_row
    
Respondeu 15/01/2014 em 20:58
fonte usuário

votos
0

usar readonlyadmin em ur amdin.py.List todos os campos que u querem fazer readonly.After criar o objeto u canot editá-los, em seguida,

usar o link

http://www.djangosnippets.org/snippets/937/

copiar o arquivo e, em seguida, importar em ur admin.py e usou-o

Respondeu 19/03/2010 em 15:00
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more