Categories
Python Answers

How to only accept a certain file type in FileField with Python Django?

To only accept a certain file type in FileField with Python Django, we can add a validator function to check the file extension.

For instance, we write

def validate_file_extension(value):
    import os
    from django.core.exceptions import ValidationError
    ext = os.path.splitext(value.name)[1]  # [0] returns path+filename
    valid_extensions = ['.pdf', '.doc', '.docx', '.jpg', '.png', '.xlsx', '.xls']
    if not ext.lower() in valid_extensions:
        raise ValidationError('Unsupported file extension.')

class Document(models.Model):
    file = models.FileField(upload_to="documents/%Y/%m/%d", validators=[validate_file_extension])

to define the validate_file_extension function to check the file extension of the selected file’s path.

We get the extension from the path with os.path.splitext(value.name)[1].

And then we check if the ext extension is in valid_extensions.

If it’s not, then we raise a ValidationError.

Next, in our Document model, we add a FileField with the validators arguments set to an array with the validate_file_extension as the value.

Then validate_file_extension when a file is uploaded.

Categories
Python Answers

How to use a UUID as a primary key in Python Django models?

To use a UUID as a primary key in Python Django models, we can create a UUIDField.

For instance, we write

import uuid
from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

to create the id UUIDField in MyUUIDModel.

And then we set the default value to the value returned by uuid.uuid4.

We set primary_key to True to make id the primary key column.

Categories
Python Answers

How to create a simple custom template tag with Python Django?

To create a simple custom template tag with Python Django, we can create a function.

For instance, we write

from django import template

register = template.Library()

@register.simple_tag
def get_rate(crit, rates):
    return rates.get(crit=crit).rate

in templatetags/video.tags.py by creating the get_rate function that returns a value and register it with the @register.simple_tag decorator.

Then in a template, we load and use the tag with

{% load video_tags %}

<div id="rating">
  <ul>
{% for crit in videofile.topic.crits.all %}
    <li>
      <div class="rateit"
        data-rateit-value="{% get_rate crit rates %}"
        data-rateit-ispreset="true"
        crit-id="{{ crit.id }}"></div>
      {{ crit }}
    </li>
{% endfor %}
  </ul>
</div>

We load it with

{% load video_tags %}

And then we use the get_rate tag with

{% get_rate crit rates %}

rates is the argument for the tag function.

Categories
Python Answers

How to override the save method in the Python Django ModelForm?

To override the save method in the Python Django ModelForm, we add the save method into our model form class.

For instance, we write

def copy_model_instance(obj):  
    initial = dict([(f.name, getattr(obj, f.name)) for f in obj._meta.fields if not isinstance(f, AutoField) and not f in obj._meta.parents.values()])  
    return obj.__class__(**initial)  

class CallResultTypeForm(ModelForm):
    callResult = ModelMultipleChoiceField(queryset=CallResult.objects.all())
    campaign = ModelMultipleChoiceField(queryset=Campaign.objects.all())
    callType = ModelMultipleChoiceField(queryset=CallType.objects.all())

    def save(self, commit=True, *args, **kwargs):
        m = super(CallResultTypeForm, self).save(commit=False, *args, **kwargs)
        results = []
        for cr in self.callResult:
            for c in self.campain:
                for ct in self.callType:
                    m_new = copy_model_instance(m)
                    m_new.callResult = cr
                    m_new.campaign = c
                    m_new.calltype = ct
                    if commit:
                        m_new.save()
                    results.append(m_new)
         return results

to create the CallResultTypeForm that has its own save method.

In it, we call the parent class’ instance save method.

And then we loop through the values in callResult to set them in the new m_new object.

And then we return the results after we call save.

Categories
Python Answers

How to limit the maximum value of a numeric field in a Python Django model?

To limit the maximum value of a numeric field in a Python Django model, we can use MaxValueValidator and MinValueValidator.

For instance, we write

from django.db.models import IntegerField, Model
from django.core.validators import MaxValueValidator, MinValueValidator

class CoolModel(Model):
    limited_integer_field = IntegerField(
        default=1,
        validators=[
            MaxValueValidator(100),
            MinValueValidator(1)
        ]
     )

to add the limited_integer_field field into the CoolModel model.

We limit the value of limited_integer_field saved by calling MaxValueValidator with 100 to set the max limited_integer_field value to 100.

And we call MinValueValidator with 1 to set the min limited_integer_field to 1.