how to filter items in django - python

I have some users in my application where some are admin and some are suppliers, I will like to filter only those that are suppliers. I have tried using some queryset but I am not getting it. I will also like some recommendation where I can learn more about to filter objects in Django or python. Thanks
models.py
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
# CUSTOM USER FIELDS
firstname = models.CharField(max_length=30)
lastname = models.CharField(max_length=30)
telephone = models.IntegerField(blank=True, null=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
class user_type(models.Model):
is_admin = models.BooleanField(default=False)
is_supplier = models.BooleanField(default=False)
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
if self.is_supplier == True:
return User.get_email(self.user) + " - is_supplier"
else:
return User.get_email(self.user) + " - is_admin"
views.py
def Viewsupplier(request):
suppliers = User.objects.filter(i am getting stuck here with the appriopriate filter)
context = {"suppliers":suppliers}
print(suppliers)
return render(request, 'core/view-suppliers.html', context)

You cann filter with:
suppliers = User.objects.filter(user_type__is_supplier=True)
If you define a relation (like a ForeignKey or OneToOneField), you can access the relation in reverse as well. If you do this in a query, It uses the related_query_name=… [Django-doc] as name for the relation in reverse. If you did not fill this in, it will take the related_name=… [Django-doc], and finally, as is here the case, default to the model name in lowercase.
We thus here filter the User objects such that we only retrieve Users for which there is a related user_type where is_supplier is True.

Related

Alter default django models tables generation

I'm trying to create two related models in django, a custom user model and a company model.
where one user belongs to one company and one company has many users.
class Company(models.Model):
name = models.CharField(max_length=255)
class User(AbstractBaseUser):
objects = UserManager()
id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, unique=True)
name = models.CharField(max_length=67)
username = models.CharField(max_length=255, unique=True)
email = models.EmailField(max_length=255, unique=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
last_login = models.DateTimeField(auto_now=True)
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_supuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
By default django generated two tables like this:
But I dont want any foreign keys directly on those tables, instead
i want a third auxiliary table with the two foreign keys from the models
like this:
How could I do something like that ?

Set the value of a field in a model as the value of a field in another model in django

I have a two model field one which is the user model and one which is the landlord model. I want the first_name and last_name of the user model to be saved also in the landlord model.
This is my model view
pass
class User(AbstractUser):
is_customer = models.BooleanField(default=False)
is_employee = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
nin = models.IntegerField(unique = True , null=True)
avatar = models.ImageField(null= True, default="avatar.svg")
objects = UserManager()
class Landlord(models.Model):
user = models.OneToOneField(User, null= True, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200, null=True)
last_name = models.CharField(max_length=200, null=True)
email = models.EmailField(unique = True , null=True)
bio = models.TextField(null=True)
nin = models.IntegerField(unique = True , null=True)
avatar = models.ImageField(null= True, default="avatar.svg")
USERNAME_FIELD = 'email'
REQUIRED_FIELDS= []
objects = User()
def __str__(self):
return str(self.user)```
Instead of creating such model decide to do one of solutions:
Inherit from User model:
class Landlord(User):
Make User universal model with a flag if it is a Landlord user:
class User(AbstractUser):
...
is_landlord = models.BooleanField(default=False)
With option 2 just everywhere you need only Landlord things use if user.is_landlord: or in templates: {% if user.is_landlord %} etc.

Django AbstractBaseUser MultipleChoiceField

I have created a custom user model with AbstractBaseUser like this:
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
preference = models.CharField(max_length=400)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'preference']
objects = CustomUserManager()
def __str__(self):
return self.email
For the preference field i don't want a char field, but to create a MultipleChoiceField and when a user sign up to choose what he/she wants from the choices. Is there a simple way to do this?
I have a similar form which i used for different purpose:
class CategoryForm(forms.Form):
def __init__(self, *args, **kwargs):
categories = kwargs.pop("Category")
super(CategoryForm, self).__init__(*args, **kwargs)
self.fields["Category"] = forms.MultipleChoiceField(choices=categories, label='Click this to select categories')
EDIT
class CustomUser(AbstractBaseUser, PermissionsMixin):
category_list = pickle.load(open("/home/anonymous/Documents/Diploma-Recommender/Recommendation/Dataset"
"/category_list.pickle", "rb"))
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
category_tuple = ((),)
for j in category_list:
category_tuple = category_tuple + ((j, j),)
category_tuple = list(category_tuple)
category_tuple.pop(0)
category_tuple = tuple(category_tuple)
preference = ArrayField(
models.CharField(choices=category_tuple, null=True, max_length=50, blank=True, default=None),
)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'preference']
objects = CustomUserManager()
def __str__(self):
return self.email
I would recommend using an ArrayField in your model if you are using postgreSQL (which you should be!). This will accomplish your goal of multiple choices in a model field.
from django.contrib.postgres.fields import ArrayField
class CustomUser(AbstractBaseUser, PermissionsMixin):
CATEGORY_1 = 'Category_1'
CATEGORY_2 = 'Category_2'
CATEGORY_3 = 'Category_3'
CATEGORY_TYPE_CHOICES = [
(CATEGORY_1, 'Category_1'),
(CATEGORY_2, 'Category_2'),
(CATEGORY_3, 'Category_3')
]
category = ArrayField(
max_length=10,
choices=CATEGORY_TYPE_CHOICES,
null=True,
default=None,
blank=True
)
Read more here: Django Model MultipleChoice
if your multiple choice is sth like active diactive
you can just specify those like this :
CHOICES = (('one','one'), ('two','two') ...)
preference = models.CharField(max_length=400, choices = CHOICES)
this works if you want to get the gender or some limited choices , but if your choices is from different model like category and there is a model Category if the number of choices is 1 ForeignKey and if it is more than 1 use ManyToMany relation in your User model
and if you use ModelForm django handles it for you.

filtering a queryset based on the results of anoter one

So I have a model called post and one of its fields is a foreign key to user model, And i have another model called subscriptions which has 2 foreign keys one referring to the user and the other one referrs to another account and i want to filter the post queryset to only show posts from people where there is a subscription object where the user is subscribed to the creator of the post. My models look like this:
class post(models.Model):
creator = models.ForeignKey(Account,blank=False,null=False,on_delete=models.CASCADE)
...
class subscriptions(models.Model):
subscriber = models.ForeignKey(Account,blank=False,null=False,on_delete = models.CASCADE, related_name='subscriber')
subscribed_to = models.ForeignKey(Account,blank=False,null=False,on_delete = models.CASCADE, related_name='subscribed_to')
i tried doing this in the views
posts = post.objects.filter(creator__in = request.user.subscribed_to)
but it return nothing
This is my account model:
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
addresse = models.CharField(max_length=60)
city = models.CharField(max_length=50)
party_count = models.IntegerField(default=0)
verified = models.BooleanField(default=False)
profil_pic = models.ImageField(upload_to='profil_pics/',blank=True)
birthday = models.DateField(default=date.today())
date_joined = models.DateTimeField(verbose_name='date_joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last_login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email','first_name','last_name','addresse','birthday','city']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self,app_label):
return True
You can solve it in one query.
Post.objects.filter(creator__subscribed_to__subscriber=request.user)
After doing some research i ended up finding some infos that lead to:
subs = subscriptions.objects.filter(subscriber=request.user).values_list('subscribed_to')
posts = post.objects.filter(creator__in = subs

django foreign key relationships

models.py
class Hub(models.Model):
name = models.CharField(max_length=150)
def __str__(self):
return self.name
class User(AbstractUser):
is_client = models.BooleanField(default=False)
is_trainer = models.BooleanField(default=False)
username = models.CharField('username', max_length=150, unique=True)
email = models.EmailField(unique=True)
hub = models.ForeignKey(Hub, on_delete=models.CASCADE, blank=True, null=True)
hub_position = models.CharField(max_length=150, default="")
mentor = models.ForeignKey('self', on_delete=models.CASCADE, blank=True,null=True)
terms = models.BooleanField(blank=True, default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'terms']
def get_absolute_url(self):
return reverse('student:dashboard', kwargs={'pk': self.pk})
Confused on how to design the models here. Each User can belong to exactly one Hub.A hub has one leader, many excoms and many members ,all of them belongs to User .The hubs are added from the admin side.Leader can accept hub joining requests from excoms and members.
I'd add the user position as a choice field to the User, so you get a nice select box in the Admin.
class User(AbstractUser):
USER_POSITIONS = ((0, 'Regular'), (1, 'Leader'), (2, 'Excom'))
hub = models.ForeignKey(Hub, on_delete=models.CASCADE, blank=True, null=True)
hub_position = models.IntegerField(default=0, choices=USER_POSITIONS, ...)

Categories

Resources