简体   繁体   中英

Django Filtering Foreign Key Item

I make simple daily cleaning check app. the app is simple, the user observe certain areas and check whether the areas are clean or not. after all checking the user needs to report to authorities that will approve his daily cleaning works. The authorities here are maker, checker and signer. cln_daily model here represent daily cleaning works that will have maker, checker and signer from User model.

I have app called user that has costumized User model in model.py

class User(AbstractUser):
    username = models.CharField(max_length=50, unique=True)
    email = models.EmailField(_('email address'), unique=True)
    phone = models.IntegerField(_('phone number'), unique=True, blank=True, null=True)

this User has ManyToMany Relationship with Group queryset: maker, checker, signer

>>> print(Group.objects.all()) 
<QuerySet [<Group: maker>, <Group: checker>, <Group: signer>]>

In other app called cleaning I have cln_daily model that has foreignkey relationship with that User model based on their group .

class cln_daily(models.Model):
   .
   .
   user_maker = models.ForeignKey(User,verbose_name="Maker's Signature",on_delete=models.CASCADE, related_name="makerSignature", blank=True, null=True,)
   user_checker = models.ForeignKey(User, verbose_name="Checker's Signature",on_delete=models.CASCADE, related_name="checkerSignature", blank=True, null=True)
   user_signer = models.ForeignKey(User, verbose_name="Signer's Signature",on_delete=models.CASCADE, related_name="signerSignature", blank=True, null=True)

So what I mean is user_maker queryset has users that only belong to group maker . user_checker has users that only belong to group checker and user_signer queryset has users that only belong to group signer . How to express filtered User model in that model.py ?

I think I got something about your problem, you wanna join tables in a simple way ,right? , I recommend to have a look at this and this

and fix these model relationship in this way because by time it would be a problem:

class cln_daily(models.Model):
   .
   .
   user_maker = models.ForeignKey(User,verbose_name="Maker's Signature",on_delete=models.CASCADE, related_name="makerSignature", blank=True, null=True,)
                                  ^^^^
   user_checker = models.ForeignKey(User, verbose_name="Checker's Signature",on_delete=models.CASCADE, related_name="checkerSignature", blank=True, null=True)
                                   ^^^^^
   user_signer = models.ForeignKey(User, verbose_name="Signer's Signature",on_delete=models.CASCADE, related_name="signerSignature", blank=True, null=True)
                                   ^^^^

instead of using User in the ForeignKeyField it would be better to user get_user_model() or using this patter as str(cause you have to import it in your code first):

class cln_daily(models.Model):
   .
   .
   user_maker = models.ForeignKey('myapp.User',verbose_name="Maker's Signature",on_delete=models.CASCADE, related_name="makerSignature", blank=True, null=True,)
   user_checker = models.ForeignKey('myapp.User', verbose_name="Checker's Signature",on_delete=models.CASCADE, related_name="checkerSignature", blank=True, null=True)
   user_signer = models.ForeignKey('myapp.User', verbose_name="Signer's Signature",on_delete=models.CASCADE, related_name="signerSignature", blank=True, null=True)

because in time it would be migrations problem specually if you are new in django

After long searched. I tricked it by solved it in forms

class MCSForm(forms.ModelForm):
    class Meta:
        model = cln_daily
        fields = ("__all__")
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['user_maker'].queryset = User.objects.filter(groups__name='maker')
        self.fields['user_checker'].queryset = User.objects.filter(groups__name='checker')
        self.fields['user_signer'].queryset = User.objects.filter(groups__name='signer')

I have better answer instead of tricking them in forms. using limit_choices_to in FKField

User = get_user_model()
class cln_daily(models.Model):
   .
   .
   user_maker = models.ForeignKey(User,verbose_name="Maker's Signature",on_delete=models.CASCADE, related_name="makerSignature", blank=True, null=True,limit_choices_to={'groups__name':'maker'})
   user_checker = models.ForeignKey(User, verbose_name="Checker's Signature",on_delete=models.CASCADE, related_name="checkerSignature", blank=True, null=True,limit_choices_to={'groups__name':'checker'})
   user_signer = models.ForeignKey(User, verbose_name="Signer's Signature",on_delete=models.CASCADE, related_name="signerSignature", blank=True, null=True,limit_choices_to={'groups__name':'signer'})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM