Search code examples
pythondjango-formsdjango-querysetdjango-widget

Django Forms with Foreign Key using Materialize


What I Want

Create the same form that shows on Django admin on templates.

The Problem

I cannot load the foreign keys into the forms. I was searching for a solution for two days. I have read the Django documentation for ModelForm and QuerySet but I cannot find the solution. If anyone here can help me, it´s gonna be awesome. Thanks for your time!

My Code

models.py:

from django.conf import settings
from django.db import models
from django.utils import timezone
from taggit.managers import TaggableManager
from ckeditor.fields import RichTextField

class Categoria(models.Model):
    categoria = models.CharField(
        max_length=200, verbose_name="Nome da categoria", 
        help_text="colocar aqui o texto de ajuda"
    )
    resumo = models.CharField(
        max_length=200, verbose_name="Resumo",
        help_text="colocar aqui o texto de ajuda"
    )
    slug = models.CharField(max_length=200, default=1)

    class Meta:
        # Gives the proper plural name for admin
        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
    )
    resumo = models.CharField(max_length=200)

    class Meta:
        verbose_name_plural = "serie"

    def __str__(self):
        return self.serie

class Artigo(models.Model):
    title = models.CharField(
        max_length=200,
        verbose_name='Título do Post',
        help_text='Procure usar um texto que seja a pergunta de um usuário: Ex. Como escolher o revestimento '
    )
    heading = models.CharField(
        max_length=250,
        verbose_name='Chamada',
        help_text='Um texto pequeno para atrair o leitor'
    )
    serie = models.ForeignKey(
        Serie,
        default='1',
        on_delete=models.SET_DEFAULT
    )
    text = RichTextField(blank=True, null=True)
    created_date = models.DateTimeField(
        default=timezone.now,
        verbose_name='Data de criação:'
    )
    published_date = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name='Data de postagem:'
    )
    slug = models.SlugField(
        unique=True,
        max_length=100,
        verbose_name='Url única:',
        help_text='A URL deve ser única, representar o conteúdo, e ser chamativa para SEO'
    )
    tags = TaggableManager(verbose_name='tags')

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

forms.py:

from django import forms
from .models import Artigo, Serie

class PostForm(forms.ModelForm):
    class Meta:
        model = Artigo
        fields = '__all__'

        widgets = {
            'title': forms.TextInput(attrs={'class': 'input', 'placeholder': 'Digite um texto'}), 
            'heading': forms.TextInput(attrs={'class': 'input', 'placeholder': 'Digite um texto'}),  
            'serie': forms.ModelChoiceField(queryset=Série.objects.all()),  
            'text': forms.Textarea(attrs={'class': 'input',}),  
            'created_date': forms.DateTimeInput(attrs={'class': 'datepicker', 'type':'datetime','placeholder': 'Digite um texto'}),
            'published_date': forms.DateTimeInput(attrs={'class': 'datepicker', 'placeholder': 'Digite um texto'}),  
            'slug': forms.TextInput(attrs={'class': 'input', 'placeholder': 'Digite um texto'}),
            'tags': forms.TextInput(attrs={'class': 'chips chips-placeholder',}),
        }`

Some Posts in StackOverflow that I have Read:

Best regards,

A.


Solution

  • Finally, I have found a solution.

    You have to be careful when using Django and Materialize at the same time.

    Material CSS is set to work with some classes and some of them need JavaScript to work correctly.

    Forms in Django are rendered in different classes, and you need to init jQuery using IDs instead of classes.

    To check what happens:

    1. Remove all CSS and reference of style (use raw HTML)
    2. If the form is rendered, your problem is not on the foreign keys

    Code example:

    Using this code on the template that renders the forms.py, I was able to find the solution

    <script>
      // datepicker for 
      $(document).ready(function () {
        $('#id_published_date, #id_created_date').datepicker();
      });
      // Select 
      $(document).ready(function () {
        $('select').formSelect();
      });
    </script>