CreateView with OneToOneField relation in one View

Viewed 309

I'm a Django beginner and try to implement a class based CreateView with two forms and an OneToOne relation but have no glue how to do this in one view.

For example: the following is given:

#models.py
# some imports..

class RedItem(models.Model):
   name = models.Charfield(max_length=255)
   storage = models.OneToOneField("Storage", on_delete=models.CASCADE)

class BlueItem(models.Model):
   name = models.Charfield(max_length=255)
   storage = models.OneToOneField("Storage", on_delete=models.CASCADE)

class Storage(models.Model):
   shelf = models.Charfield(max_length=255)
   room = models.Charfield(max_length=255)

...the View:

#views.py
from django.views.generic.edit import CreateView
from .models import RedItem, BlueItem, Storage
# some other imports..

class RedItemCreate(CreateView):
   model = RedItem
   fields = ['name']
   template_name_suffix = "_form"

```html
and a Form:
```html
<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save">
</form>

The question is now how can a user fill in both (e.g. RedItem + Storage) in one batch? Thanks in advance for any direction.

Update and a working approach: I have to create forms in forms.py and add it the the CreateView.

#urls.py
from django.urls import path
from .views import *

urlpatterns = [
    path('reditemlist/', ExampleList.as_view(), name='example_list'),
    path('reditemcreate/', ExampleCreate.as_view(),  name='example_create')
]
#forms.py
from django.forms import ModelForm
from .models import RedItem, Storage

class RedItemForm(ModelForm):
    class Meta:
        model = RedItem
        fields = ['name']

class StorageForm(ModelForm):
    class Meta:
        model = Storage
        fields = ['shelf']

And the CreateView:

#views.py
from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView
from .models import *
from .forms import *
from django.urls import reverse_lazy

class ExampleList(ListView):
    model = RedItem

class ExampleCreate(CreateView):
    model = RedItem
    form_class = RedItemForm
    success_url = reverse_lazy('example_list')
    
    def get_context_data(self, **kwargs):
        context = super(ExampleCreate, self).get_context_data(**kwargs)
        if self.request.POST:
            context['reditem'] = RedItemForm(self.request.POST)
            context['storage'] = StorageForm(self.request.POST)
        else:
            context['reditem'] = RedItemForm()
            context['storage'] = StorageForm()
        return context 

    def form_valid(self, form):
        context = self.get_context_data()
        storage = context['storage']
        if storage.is_valid() and form.is_valid():
            f = form.save()
            shelf = storage.save(commit = False)
            shelf.reditem = f
            shelf.save()
        return super().form_valid(form)
<form method="post">{% csrf_token %}
    {{ form.as_p }}
    {{ storage.as_p }}
    <input type="submit" value="Save">
</form>

Next stop: UpdateView

0 Answers
Related