django admin-모델의 일부가 아닌 사용자 정의 양식 필드 추가


106

관리 사이트에 등록 된 모델이 있습니다. 필드 중 하나는 긴 문자열 표현식입니다. 이 필드 값을 기반으로 긴 문자열 표현식을 빌드하고 관련 모델 필드에 저장하는 관리자의이 모델의 추가 / 업데이트 페이지에 사용자 정의 양식 필드를 추가하고 싶습니다.

어떻게 할 수 있습니까?

업데이트 : 기본적으로 내가하고있는 것은 기호에서 수학 또는 문자열 표현식을 작성하는 것입니다. 사용자는 기호를 선택하고 (모델의 일부가 아닌 사용자 정의 필드) 저장을 클릭하면 다음에서 문자열 표현식 표현을 만듭니다. 심볼 목록을 작성하여 DB에 저장합니다. 심볼이 모델과 DB의 일부가 아니라 최종 표현 일뿐입니다.

답변:


156

admin.py 또는 별도의 forms.py에서 ModelForm 클래스를 추가 한 다음 평소와 같이 추가 필드를 선언 할 수 있습니다. 또한 form.save ()에서 이러한 값을 사용하는 방법에 대한 예제를 제공했습니다.

from django import forms
from yourapp.models import YourModel


class YourModelForm(forms.ModelForm):

    extra_field = forms.CharField()

    def save(self, commit=True):
        extra_field = self.cleaned_data.get('extra_field', None)
        # ...do something with extra_field here...
        return super(YourModelForm, self).save(commit=commit)

    class Meta:
        model = YourModel

추가 필드가 관리자에 표시되도록하려면 :

  1. admin.py를 편집하고 위에서 만든 양식을 참조하도록 양식 속성을 설정하십시오.
  2. 필드 또는 필드 세트 선언에 새 필드 포함

이렇게 :

class YourModelAdmin(admin.ModelAdmin):

    form = YourModelForm

    fieldsets = (
        (None, {
            'fields': ('name', 'description', 'extra_field',),
        }),
    )

업데이트 : django 1.8에서는 fields = '__all__'YourModelForm의 메타 클래스에 추가해야합니다 .


2
네, 정말 이유를 알고 싶습니다
Vishnu

13
당신은 추가해야합니다 fields = '__all__'당신에 Meta, 그렇지 않으면 장고 불평 클래스 :Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is deprecated
IsaacKleiner

1
@sthzg, 정확하지 않기 때문입니다. 그것은 나에게 오류를 준다 :YourModelAdmin.list_display[0], 'extra_field' is not a callable or an attribute of 'YourModelAdmin' or found in the model 'YourModel'.
Cerin

7
어떤 이유에서든을 받으면 정의에 를 AttributeError: Unable to lookup "extra_field"...추가해보십시오 . 에 장고하려고보고, 그것을 위해 레이블을 "추측"것으로 보인다 과 같은 속성 정의에 대해. labelextra_fieldModelModelAdmin
alxs 2017

1
extra_field가 CharField ()이면 아름답게 작동했습니다. hiddenField [Django 1.11]이면 오류가 발생 Unknown field(s) (extra_field) specified for YourModel. Check fields/fieldsets/exclude attributes of class YourModelAdmin.합니다. 이에 대한 해결 방법은extra_field = forms.CharField(widget=forms.HiddenInput())
kakoma

35

관리자에서 할 수는 있지만 매우 간단한 방법은 없습니다. 또한 대부분의 비즈니스 로직을 모델에 유지하도록 조언하고 싶습니다. 따라서 Django Admin에 의존하지 않을 것입니다.

모델에 두 개의 개별 필드가 있으면 더 쉬울 수도 있고 더 좋을 수도 있습니다. 그런 다음 모델에이를 결합하는 방법을 추가합니다.

예를 들면 :

class MyModel(models.model):

    field1 = models.CharField(max_length=10)
    field2 = models.CharField(max_length=10)

    def combined_fields(self):
        return '{} {}'.format(self.field1, self.field2)

그런 다음 관리자 combined_fields()에서 읽기 전용 필드로 추가 할 수 있습니다 .

class MyModelAdmin(models.ModelAdmin):

    list_display = ('field1', 'field2', 'combined_fields')
    readonly_fields = ('combined_fields',)

    def combined_fields(self, obj):
        return obj.combined_fields()

당신이를 저장하려면 combined_fields데이터베이스에 때 모델 저장 당신은 또한 저장할 수 :

def save(self, *args, **kwargs):
    self.field3 = self.combined_fields()
    super(MyModel, self).save(*args, **kwargs)

4
답변 해 주셔서 감사합니다.하지만 이것은 제가 찾고있는 것이 아닙니다. 사용자 지정 필드를 DB에 저장하지 않고 계산 된 문자열 만 저장하고 싶습니다. 기본적으로 내가하는 일은 기호에서 수학적 또는 문자열 표현식을 작성하는 것입니다. 사용자는 기호를 선택하고 (모델의 일부가 아닌 사용자 정의 필드) 저장을 클릭하면 다음 목록에서 문자열 표현식 표현을 만듭니다. 기호를 DB에 저장합니다.
michalv82 2013

@ michalv82 모델의 save()방법으로 데이터베이스에 저장하고 내 답변의 업데이트를 확인할 수도 있습니다.
gitaarik 2013

1
다시 한번 감사하지만, 문제는 내가 마지막 필드 (즉, 기호)를 결합 필드를 저장하지 않는다는 것입니다, 난 그냥 최종 문자열을 저장할
michalv82

2 개의 필드를 저장하는 것이 문제입니까? 결합 된 필드가 어떻게 생성되었는지 알고 싶다면 유용 할 수 있습니다.
gitaarik 2013

6
다시 한 번 감사하지만 2 필드가 아니라 아마도 더 많을 것입니다. 다시 말하지만 DB에 저장하고 싶지 않으므로이 솔루션이 작동하지 않습니다.
michalv82 2013

5

Django 2.1.1 기본 답변은 내 질문에 대한 대답을 중간에 얻었습니다. 실제 모델의 필드에 결과를 저장하는 데 도움이되지 않았습니다. 제 경우에는 사용자가 데이터를 입력 할 수있는 텍스트 필드를 원했고 저장이 발생하면 데이터가 처리되고 결과가 모델의 필드에 입력되어 저장됩니다. 원래 답변은 추가 필드에서 값을 얻는 방법을 보여 주었지만 적어도 Django 2.1.1에서는 모델에 다시 저장하는 방법을 보여주지 않았습니다.

이것은 바인딩되지 않은 사용자 정의 필드에서 값을 가져 와서 처리하여 실제 설명 필드에 저장합니다.

class WidgetForm(forms.ModelForm):
    extra_field = forms.CharField(required=False)

    def processData(self, input):
        # example of error handling
        if False:
            raise forms.ValidationError('Processing failed!')

        return input + " has been processed"

    def save(self, commit=True):
        extra_field = self.cleaned_data.get('extra_field', None)

        # self.description = "my result" note that this does not work

        # Get the form instance so I can write to its fields
        instance = super(WidgetForm, self).save(commit=commit)

        # this writes the processed data to the description field
        instance.description = self.processData(extra_field)

        if commit:
            instance.save()

        return instance

    class Meta:
        model = Widget
        fields = "__all__"

4

언제든지 새 관리자 템플릿을 만들고 admin_view에서 필요한 작업을 수행 할 수 있습니다 (admin_view에 대한 관리자 추가 URL 재정의) :

 url(r'^admin/mymodel/mymodel/add/$' , 'admin_views.add_my_special_model')

3

두 개의 개별 필드가 아닌 결합 된 필드 만 모델에 저장하려는 경우 다음과 같이 할 수 있습니다.

나는 이런 일을 한 적이 없기 때문에 어떻게 될지 완전히 확신하지 못합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.