Categories
Python Answers

How to with upload_to determined at runtime with a Python Django FileField?

To with upload_to determined at runtime with a Python Django FileField, we can set the upload_to path dynamically in a FileField.

For instance, we write

def content_file_name(instance, filename):
    return '/'.join(['content', instance.user.username, filename])

class Content(models.Model):
    name = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    file = models.FileField(upload_to=content_file_name)

to create the content_file_name function to compute the path of the file path to save to return it.

And then we create the file FileField in the Content model by setting the upload_to argument to the content_file_name function so that it’s run at runtime to determine the upload path.

Categories
Python Answers

How to do an OR filter in a Python Django query?

To do an OR filter in a Python Django query, we can use Q and the | operator.

For instance, we write

from django.db.models import Q

Item.objects.filter(Q(creator=owner) | Q(moderated=False))

to call filter to search for Item items where creator is owner or moderated is False.

We call Q with the conditions we want and combine them with | to do the OR query.

Categories
Python Answers

How to pass custom form parameters to Formset with Python Django?

To pass custom form parameters to Formset with Python Django, we call formset_factory and functools.partial.

For instance, we write

from functools import partial, wraps
from django.forms.formsets import formset_factory

ServiceFormSet = formset_factory(wraps(ServiceForm)(partial(ServiceForm, affiliate=request.affiliate)), extra=3)

to wrap the ServiceForm with wraps.

And then we call partial with Service and the argument we want to pass into ServiceForm.

And then we call (wraps(ServiceForm with the result returned by partial.

And then we call formset_factory on the result returned by wraps.

Categories
Python Answers

How to programmatically saving image to Python Django ImageField?

To programmatically saving image to Python Django ImageField, we can call save with the path we want to save the file to.

For instance, we write

from django.core.files import File 
import urllib

result = urllib.urlretrieve(image_url)

self.photo.save(
    os.path.basename(self.url),
    File(open(result[0], 'rb'))
    )

self.save()

in a model class method.

We call save on the photo ImageField with the path to save to as the argument.

And we save the file that we opened from urllib.urlretrieve method by creating a File object from it.

We create the file by call open with the result[0] file with read permission.

Finally, we call self.save to save the model data.

Categories
Python Answers

How to dynamically add field to a form with Python Django?

To dynamically add field to a form with Python Django, we can add the form with a for loop.

For instance, we write

class MyForm(forms.Form):
    original_field = forms.CharField()
    extra_field_count = forms.CharField(widget=forms.HiddenInput())

    def __init__(self, *args, **kwargs):
        extra_fields = kwargs.pop('extra', 0)

        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['extra_field_count'].initial = extra_fields

        for index in range(int(extra_fields)):
            self.fields['extra_field_{index}'.format(index=index)] = \
                forms.CharField()

to create the MyForm form that has a for loop in the __init__ method that creates CharFields and add them into the self.fields dictionary dynamically.

Then in our view, we can use the form with

def myview(request):
    if request.method == 'POST':
        form = MyForm(request.POST, extra=request.POST.get('extra_field_count'))
        if form.is_valid():
            print "valid!"
    else:
        form = MyForm()
    return render(request, "template", { 'form': form })

We set the extra argument to a list we get from request.POST.get.

Then we render the template for the view with

<form>
    <div id="forms">
        {{ form.as_p }}
    </div>
    <button id="add-another">add another</button>
    <input type="submit" />
</form>