Fill out Django form with data obtained from URL

Viewed 31

I want to create a new Fallacy (see models.py) via the form to which I get over the url path('<slug:slug_tree>/new/', views.CreateFallacyView.as_view(), name='create_fallacy'),. So the user is on the TreeDetailView (which corresponds to a certain Tree), and he can add a new Fallacy to this tree. The user should input title and detail, but the Tree (ForeignKey) should be assigned in the code. It should be assigned to the corresponding Tree from which he was directed to the CreateFallacyView. The slug of the tree is inside the URL, so I thought I could use that information somehow, but I have no idea how I can proceed with that information. Any help is appreciated! Or probably there are other more elegant solutions?

Many thanks!

models.py

class Tree(models.Model):
    title = models.CharField(max_length=50)
    detail = models.TextField()
    slug = models.SlugField(allow_unicode=True, unique=True, null=True, blank=True)
    
class Fallacy(models.Model):
    title = models.CharField(max_length=50)
    detail = models.TextField()
    tree = models.ForeignKey(Tree, related_name='fallacy', on_delete=models.CASCADE)
      

views.py

class CreateFallacyView(generic.CreateView):
    form_class = forms.FallacyForm

forms.py

class FallacyForm(forms.ModelForm):

    class Meta:
        model = models.Fallacy
        fields = ('title', 'detail')

urls.py

app_name = 'argtree'

urlpatterns = [
    path('', views.TreeListView.as_view(), name='all'),
    path('<slug:slug_tree>/', views.TreeDetailView.as_view(), name='tree_detail'),
    path('<slug:slug_tree>/new/', views.CreateFallacyView.as_view(), name='create_fallacy'),
1 Answers

In the CreateFallacyView you can link it to the given Tree in the .form_valid(…) method [Django-doc] with:

from django.shortcuts import get_object_or_404

class CreateFallacyView(generic.CreateView):
    form_class = forms.FallacyForm
    
    def form_valid(self, form):
        tree = get_object_or_404(Tree, slug=self.kwargs['slug_tree'])
        form.instance.tree = tree
        return super().form_valid(form)
Related