Search code examples
pythondjangodjango-class-based-viewsdjango-generic-views

How to get the Foreign Key set on the URL and use it on django CreateView


Thanks for your time...

If someone can help me to get the foreign key that shows on the URL and use it on Django CreateView.

I am trying to create a simple app to organize legislation. For this, I have this relation on my database: Categoria has many Series and Series has many posts.

I have made the one path of urls.py like this

(...)
path('nova-serie/<categoria>', NovaSerie.as_view(), name='nova_serie'), 
(...)

I just want to pass get the value from the URL and save as the foreign key without the user have to type it again.

I want to get the foreign key and save it without the user has to type it again

view.py

class NovaCategoria(CreateView):
    model = Categoria
    form_class = CategoriaForm
    template_name = 'nova_categoria.html'
    success_url = reverse_lazy('home')

class NovaSerie(CreateView):
    model = Serie
    form_class = SerieForm
    template_name = 'nova_serie.html'
    success_url = reverse_lazy('home')

models.py

class Categoria(models.Model):
    categoria = models.CharField(
        max_length=200, verbose_name="Nome da categoria", help_text="colocar aqui o texto de ajuda")
   
    class Meta:
        verbose_name_plural = "Categorias"
        verbose_name = "categoria"

    def __str__(self):
        return self.categoria

class Serie(models.Model):
    serie = models.CharField(
        max_length=200, verbose_name="Série", help_text="colocar aqui o texto de ajuda")
    categoria = models.ForeignKey(Categoria, default=1, on_delete=models.SET_DEFAULT)
    
    class Meta:
        verbose_name_plural = "serie"

    def __str__(self):
        return self.serie

forms.py

class SerieForm(forms.ModelForm):
    class Meta:
        model = Serie
        fields = (
            'serie',
            'categoria',
        )
        widgets = {
            'title': forms.TextInput(),  # attrs={class="title"}
            'categoria': forms.TextInput(attrs={'class': "green", 'value': object }),  # attrs={class="title"}
        }

class CategoriaForm(forms.ModelForm):
    class Meta:
        model = Categoria
        fields = (
            'categoria',
        )
        widgets = {
            'title': forms.TextInput(),  # attrs={class="title"}
        }

If you have found any issues with this post, please let me know. I will be glad to change it.

Thanks.


Solution

  • To make this happen we need to make basically two things:

    1. on url.py we need to tell Django that it´s an integer
    2. on views.py use the form_valid

    url.py

    so your urls.py should have something like that:

    path('nova-serie/<int:categoria>', NovaSerie.as_view(), name='nova_serie'),
    

    views.py

    class NovaSerie(CreateView):
        model = Serie
        form_class = SerieForm
        template_name = 'nova_serie.html'
        success_url = reverse_lazy('home')
    
        def form_valid(self, form):
            form.instance.categoria_id = self.kwargs['categoria']
            return super().form_valid(form)
    

    With those changes, I was able to make it happens!

    I am a newbie, if I should edit or delete this post, please let me know

    The solution was given by mr. @Willem Van Onsem