简体   繁体   中英

Django : ModelForm with OneToOneField

I have 2 models linked by a OneToOneField :

class User(models.Model):
    name = models.CharField(max_length=100, unique=True)
    email = models.EmailField(blank=True)
    base = models.OneToOneField(BaseUser)
    ...

class BaseUser(models.Model):
    enabled = models.BooleanFiled(default=True)
    ...

I use a ModelForm to display the user's attributes :

class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['name', 'email', ...]

And in my views :

class UserCreate(generic.CreateView):
    model = User
    template_name = 'user/create.html'
    success_url = reverse_lazy('users:list')
    form_class = UserForm

I would like to change the enabled attribute in the user's template, but I have just access to the User 's fields (name, email...).

How can I make it please ?

You can render 2 forms in your template:

def user_create(request):
    if request.method == "POST":
        user_form = UserForm(data=request.POST)
        baseuser_form = BaseUserForm(data=request.POST)
        if user_form.is_valid() and baseuser_form.is_valid():
            base_user = baseuser_form.save()
            user = user_form.save(commit=False)
            user.base = base_user
            user.save()
            return redirect(reverse_lazy('users:list'))
        else:
            ....
    else:
        user_form = UserForm()
        baseuser_form = BaseUserForm()
        return render_to_response('user/create.html', {'user_form': user_form, 'baseuser_form': baseuser_form})

If you only have one additional field you want to add, you could add it to the UserForm .

class UserForm(ModelForm):

    enabled = forms.BooleanField(default=True)

    class Meta:
        model = User
        fields = ['name', 'email', ...]

Then, in your form_valid method you can set the value for the base_user . Since it's a create view, I'm assuming you have to create it first.

class UserCreate(generic.CreateView):

    def form_valid(self, form):
        base_user = BaseUser.objects.create(
            enabled=form.cleaned_data['enabled']
        )
        form.instance.base = base_user
        return super(UserCreate, self).form_valid(form)

If you want to add more than one extra field, then you probably want separate forms for BaseUser and User . In this case, extending CreateView gets a bit tricky, and it might be simpler to use a function based view like in Rohit's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM