Below the Radar
Below the Radar

Reputation: 7635

Django - Model best practice when fields need to be repeated

I have a model where some fields could be repeated between 0 and 5 times for the same object.

models.py:

class FusionTableLayer(models.Model):
    layer_name = models.SlugField(max_length=50)
    condition1 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    condition2 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    condition3 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    condition4 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    condition5 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option1 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option2 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option3 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option4 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option5 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option6 = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    ...etc

My question is it better to create a second model with the fields that could be duplicated and use a ForeignKey to link them?

models.py:

class EzApp(models.Model):
    layer_name = models.SlugField(max_length=50)



class EzAppOptions(models.Model):
    app = models.ForeignKey(EzApp)
    condition = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option = models.CharField('SQL Query Conditions', max_length=100, blank=True

I know it looks neat like this, but I found it more complicated to adapt forms, views and template to works with a second models with ForeignKey relationship. For instance, I have to manage two different formsets in the same view. What would be the best practice in this case?

Upvotes: 2

Views: 782

Answers (2)

catherine
catherine

Reputation: 22808

models.py

class EzApp(models.Model):
    layer_name = models.SlugField(max_length=50)

    def __unicode__(self):
        return self.layer_name

class EzAppOptions(models.Model):
    app = models.ForeignKey(EzApp)
    condition = models.CharField('SQL Query Conditions', max_length=100, blank=True)
    option = models.CharField('SQL Query Conditions', max_length=100, blank=True

    def __unicode__(self):
        return self.condition

forms.py

class EzAppForm(ModelForm):
    class Meta:
        model = EzApp


OptionFormset = inlineformset_factory(EzApp, EzAppOptions, 
    fields=('condition', 'option'), can_delete=True)

views.py

def view_name(request):
    form = EzAppForm()
    formset = OptionFormset(instance=EzApp())
    return render(request, "page.html", {
        'form': form, 'formset': formset
    })

template.html

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    {{ formset.as_p }}
    <input type="submit" value="Save"/>
</form>

Upvotes: 2

Matt
Matt

Reputation: 10312

Take a look at ForeignKey and inline formsets for dealing with situations like this.

Upvotes: 3

Related Questions