Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fields and base_fields - Django

When creating a flatpage, I want the user to select a template from a predefined list. In order to keep the Flatpage model untouched, I prefer ChoiceField over ModelChoiceField (the latter provides the PK of the template, but I need the name for the template_name field):

class NewFlatpageForm(FlatpageForm):

    template_name = forms.ChoiceField(choices = [])
    def __init__(self, *args, **kwargs):
        self.base_fields['template_name'].choices = ProjectTemplate.objects.values_list('path', 'name')
        super(NewFlatpageForm, self).__init__(*args, **kwargs)

I override __init__ or Django populates choices at server start and does not update the list then.

I don't have any admin experience, but I did similar things using the fields attribute when not using admin. However in this case, I got an exception telling fields is not an attribute of the form. __dict__ showed me there's a base_fields attribute and using it works. So, why use base_fields here, and why is fields not present and finally am I doing something hacky?

like image 772
shanyu Avatar asked Jan 26 '10 16:01

shanyu


People also ask

What are fields in django?

Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField.

What is Is_valid () in django?

The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute. Let's see an example that takes user input and validate input as well.

How do you exclude a specific field from a ModelForm?

Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.

How do you make a field non editable in django?

Every field comes in with built-in validations from Django validators. One can also add more built-in field validations for applying or removing certain constraints on a particular field. editable=False will make the field disappear from all forms including admin and ModelForm i.e., it can not be edited using any form.


2 Answers

fields doesn't exist until after you've called super. So just swap the order of the lines, so that super comes first.

like image 121
Daniel Roseman Avatar answered Nov 02 '22 19:11

Daniel Roseman


In addition to Joe Germuska. If you truly need to change the form based on the request, you can use a deepcopy to make sure nothing is changed by reference:

def get_form(self, request, obj=None, **kwargs):
    form = super(ResourceAdmin, self).get_form(request, obj, **kwargs)
    form = copy.deepcopy(form)

    if obj:
        form.base_fields['email'] = EmailField(initial=obj.user.email)
    if not request.user.is_superuser:
        form.base_fields['user'].widget = HiddenInput(attrs={'class': 'hide_form_row'})

    return form
like image 27
Rune Kaagaard Avatar answered Nov 02 '22 20:11

Rune Kaagaard