I have a Django app which keeps inventory.  There are two relevant classes 
here, one named Jar and another named Crate.  The Jar class has an 
attribute crate which is a foreign key for the Crate class.  The Crate 
class has an attribute capacity of type models.IntegerField which 
represents the maximum number of Jar objects that it can hold.  The Crate 
class also has a property "jars" which returns "self.jar_set.filter(
is_active=True).count()" or in other words, the number of Jar objects with 
is_active set to True that are associated with that Crate object.

This code is from models.py and shows the two object classes:

class Crate(models.Model):
    number = models.IntegerField()
    slug = models.SlugField(max_length=10, unique=True, blank=True)
    capacity = models.IntegerField(default=12)
    # bin where the crate can currently be found
    bin = models.ForeignKey(Bin)


    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


    class Meta:
        ordering = ['number']


    @property
    def jars(self):
        return self.jar_set.filter(is_active=True).count()


    @property
    def shortname(self):
        return "C%d" % self.number


    @property
    def longname(self):
        return "Crate %d" % self.number


    @property
    def name(self):
        return self.longname


    def __str__(self):
        return self.name


    def save(self, *args, **kwargs):
        self.slug = 'c%d' % self.number
        super(Crate, self).save(*args, **kwargs)


    def get_absolute_url(self):
        return reverse('inventory_crate', kwargs={'crate_slug': self.slug})


    def clean(self):
        # ensure that the current number of jars is less than or equal to 
the capacity
        if self.jars > self.capacity:
            raise ValidationError('Capacity of crate exceeded')




class Jar(models.Model):
    product = models.ForeignKey(Product)
    number = models.IntegerField()
    slug = models.SlugField(max_length=13, unique=True, blank=True)
    # volume in liters
    volume = models.IntegerField(default=1)
    crate = models.ForeignKey(Crate)
    # is_active = not yet sold
    is_active = models.BooleanField(default=True)
    # is_available = considered 'in stock'
    is_available = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


    objects = models.Manager()
    instock = InStockJarManager()


    class Meta:
        ordering = ['created_at']
        unique_together = ('product', 'number')


    @property
    def name(self):
        return "%s%d" % (self.product, self.number)


    def __str__(self):
        return self.name


    def save(self, *args, **kwargs):
        self.slug = ''.join([self.product.slug, str(self.number)])
        super(Jar, self).save(*args, **kwargs)


    def get_absolute_url(self):
        return reverse('inventory_jar', kwargs={'jar_slug': self.slug})


I have written an admin action named "move_multiple_jars" on the JarAdmin 
class which allows me to select multiple Jar objects and move them to a 
particular Crate object.  Right now, the intermediate page for that admin 
action has a form "MoveMultipleJarsForm" with a drop down list which 
contains all Crate objects sorted by number.  This admin action works in 
that it does move the Jar objects from one Crate object to another.  I 
would like that drop down list to contain only the Crate objects which have 
sufficient extra capacity to hold the number of Jar objects selected.

This code is from admin.py:

class JarAdmin(SmarterModelAdmin):
    valid_lookups = ('product',)
    form = JarAdminForm
    list_display = ('product', 'number', 'is_active', 'is_available', 
'crate',)
    list_display_links = ('number',)
    list_filter = ('product', 'crate', 'is_active')
    list_per_page = 50
    ordering = ['-created_at', 'is_active']
    search_fields = ['product', 'crate']
    readonly_fields = ('created_at', 'updated_at',)
    actions = ['move_multiple_jars']


    class MoveMultipleJarsForm(forms.Form):
        # JMT: this needs to somehow be restricted to those crates that 
have room
        dest = forms.ModelChoiceField(queryset=Crate.objects.all().order_by(
'number'))


    def move_multiple_jars(self, request, queryset):
        form = None


        if 'apply' in request.POST:
            form = self.MoveMultipleJarsForm(request.POST)


            if form.is_valid():
                dest = form.cleaned_data['dest']


                count = 0
                for jar in queryset:
                    jar.crate = dest
                    jar.save()
                    count += 1


                plural = ''
                if count != 1:
                    plural = 's'


                self.message_user(request, "Successfully moved %d jar%s to 
%s" % (count, plural, dest))
                return HttpResponseRedirect(request.get_full_path())
        if not form:
            form = self.MoveMultipleJarsForm()


        return render(request, 'admin/move_multiple_jars.djhtml', {
            'jars': queryset,
            'move_multiple_jars_form': form,
            })


    move_multiple_jars.short_description = "Move multiple jars to new crate"




admin.site.register(Jar, JarAdmin)


I don't know if it helps, but this is the content of 
admin/move_multiple_jars.djhtml:

{% extends "admin/base_site.html" %}


{% block content %}


<p>Moving multiple jars from crate {{ crate.name }}:</p>


<form action="" method="post">
    {% csrf_token %}


    <p>Move the following jars:</p>


    <ul>
        {% for jar in jars %}
        <li>
            {{ jar }}
            <input type="hidden" name="_selected_action" value="{{ jar.pk 
}}">
        </li>
        {% endfor %}
    </ul>


    {{ move_multiple_jars_form }}


    <input type="hidden" name="action" value="move_multiple_jars" />
    <input type="submit" name="apply" value="Move jars" />
</form>


{% endblock %}



Thank you in advance for any help you may be able to give!

Jack.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/c18c7558-55ac-4da2-9fd1-22392090ecf1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to