Search code examples
djangodjango-modelsdjango-formsdjango-managers

Django form override ForeignKey queryset


I was making a form for creation unpublished Artist instances and then adding Artwork to the artist before publishing.

I have manager to hide published=False artists and do not know how to bypass this yet in ForeignKey.

models.py

class PublishedManager(models.Manager):
    """Returns only published Artists in queryset"""
    def get_query_set(self):
        qs = super(VisibleManager, self).get_query_set()
        qs = qs.filter(status='published')
        return qs

class Artist(models.Model):
    objects = PublishedManager() # Used overall on the site to hide published=False objects
    admin_objects = models.Manager() # Default manager Will be used in admin to show invisible     objects too

class Artwork(models.Model):
    artist= models.ForeignKey(Artist)

forms.py

class ArtworkForm(forms.ModelForm):


    def __init__(self,  *args, **kwargs):
        super(ArtworkForm,self).__init(args,kwargs)
        from django.db import models
        self.fields['artist'].queryset = Artist.admin_objects.all()

shell

>>> form=Artwork_form(artist=180) #unpublished artist pk
>>> form.errors

Model artist with pk 180 does not exist

I need to make the form "see" the unpublished artists in FK, how can i achieve this?

Thank you.


Solution

  • I found the solution!!!

    Original info is here http://www.hoboes.com/Mimsy/hacks/custom-managers-django-foreignkeys/

    I implemented the CustomManagerForeignKey as the autor of this post had written with the one exception(otherwise in won't work properly):

    usage:

    class Artwork(models.Model):
        artist= CustomManagerForeignKey(Artist, manager=Artist.admin_objects)
    

    and a fix for this in the CustomManagerForeignKey:

    class CustomManagerForeignKey(models.ForeignKey):
        def __init__(self, *args, **kwargs):
            if 'manager' in kwargs:
                self.customManager = kwargs['manager'] #Here i removed the () in the end of the line
                del kwargs['manager']
            else:
                self.customManager = None
            super(CustomManagerForeignKey, self).__init__(*args, **kwargs)