Making a GET request with filter - python

My model is the following
class PokerRoom(models.Model):
STATUS = (("Pending", "Pending"), ("Finished", "Finished"))
status = models.CharField(
max_length=11,
choices=STATUS,
verbose_name=_("Status da Story"),
default="Pending",
)
name = models.CharField(max_length=200, verbose_name=_("room name"), validators=[alphanumeric])
slug = models.CharField(max_length=200, verbose_name=_("room slug"), null=True, blank=True)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
styleCards = MultiSelectField(choices=CHOICES, default=FIBONACCI)
datetime = models.DateTimeField(null=True, blank=True)
date = models.CharField(max_length=10, null=True, blank=True)
user = models.ForeignKey(User, on_delete=DO_NOTHING)
first_name_user = models.CharField(
max_length=200, verbose_name=_("user name"), null=True, blank=True
)
deck = models.ForeignKey(Pack, on_delete=models.CASCADE)
index = models.IntegerField(
null=True, blank=True, verbose_name=_("story being voted")
)
I'm my application, I want to make a searchbar for "status" and "name" and do a GET request with those filter that would be provided by the client when he make the search. But I don't know how to do that in my views.py
I was thiking in a GET method like this, but I don't know how to get the planningName and planningStatus from the frontend.
def get(self, request, pk):
"""GET of PokerRoom historic"""
user = request.user
pk = self.kwargs["pk"]
planningName =
planningStatus =
moderatorRoom = PokerRoom.objects.values("id", "first_name_user", "date", "name", "status", "styleCards", "datetime", 'slug'
).filter(Q(user= user) | Q(name=planningName) | Q(status=planningStatus)).order_by("-datetime")
Can someone helpe me?

Suppose the name of the input field is planningName, you can get the value in views.py by using
planningName = request.GET.get('planningName')
planningStatus = request.GET.get('planningStatus')

Related

Django Relational managers

I was trying to delete my Apllication model:
class Application(models.Model):
app_type = models.ForeignKey(ApplicationCategory, on_delete=models.CASCADE, related_name='applications')
fio = models.CharField(max_length=40)
phone_number = models.CharField(max_length=90)
organisation_name = models.CharField(max_length=100, null=True, blank=True)
aid_amount = models.PositiveIntegerField()
pay_type = models.CharField(max_length=1, choices=PAY_CHOICES, default=PAY_CHOICES[0][0])
status = models.ForeignKey(AppStatus, on_delete=models.CASCADE, related_name='applications', null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
benefactor = models.ForeignKey(Benefactor, on_delete=models.CASCADE, related_name='applications', null=True)
def __str__(self):
return f"id={self.id} li {self.fio} ning mablag\'i!"
and this was my Benefactor model:
class Benefactor(models.Model):
fio = models.CharField(max_length=255)
phone_number = models.CharField(max_length=9)
image = models.ImageField(upload_to='media/')
sponsory_money = models.IntegerField()
organisation_name = models.CharField(max_length=55, null=True, blank=True)
def __str__(self):
return f"{self.fio}"
But I got the below message on superAdmin Panel:
TypeError at /admin/api/benefactor/
create_reverse_many_to_one_manager.\<locals\>.RelatedManager.__call__() missing 1 required keyword-only argument: 'manager'
I would expect delete smoothly!!
Your Benefactor model has several ForeignKey relationships that share the related_name. Give each a unique name and rerun your migrations.

Cannot assign "'Sample Category'": "Product.category" must be a "Category" instance

While creating new products I'm getting such kind of error. Can someone help me?
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name_geo = models.CharField(max_length=200, null=True, blank=True)
image = models.ImageField(null=True, blank=True, default='/placeholder.png')
brand = models.CharField(max_length=200, null=True, blank=True)
category = models.ForeignKey(Category, null=False, default=0, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
countInStock = models.IntegerField(null=True, blank=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def __str__(self):
return self.name_geo
class Category(models.Model):
_id = models.AutoField(primary_key=True, editable=False)
name = models.CharField(max_length=200, null=True, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
#api_view(['POST'])
def createProduct(request):
user = request.user
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category="Sample Category",
price=0,
brand='Sample Brand',
countInStock=0,
)
serializer = ProductSerializer(product, many=False)
return Response(serializer.data)
Without separating category class in models.py everything works fine. I mean If i didn't use ForeignKey in Products class for category
It just has to be a Category Instance/Object
product = Product.objects.create(
user=user,
name_geo="Sample Name",
category=Category.objects.get_or_create(name="Sample Category"),
price=0,
brand='Sample Brand',
countInStock=0,
)
Notes:
You could just do a .get() or a .filter().first() if you don't want to create
If you use a form, you can get away with just the Category's PK/_id in the POST
this type of thing: f = form(request.POST) f.is_valid() f.save()
At the end that field will hold the PK/_id/Row# of the Category Obj

How to display only the appointments that the current logged in user has made instead of fetching up all the appointments from the database in Django

This the views.py file.
How can i display the appointments made by the current logged in user?
def user(request):
client = Client.objects.all()
appointments = Appointment.objects.all()
context = {'appointments': appointments, 'client': client,
}
return render(request, 'users/user.html', context)
Here is my Models.py. I need to display the appointments by a user when they are logged in to their profile.
class Appointment(models.Model):
CATEGORY = (
('Plumbing', 'Plumbing'),
('Electrical', 'Electrical'),
('Cleaning', 'Cleaning'),
)
STATUS = (
('Pending', 'Pending'),
('Delivered', 'Delivered'),
)
user = models.ForeignKey(Client, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=200, null=True)
worker = models.ForeignKey(Worker, null=True, on_delete=models.SET_NULL)
category = models.CharField(max_length=200, null=True, choices=CATEGORY)
task_date = models.DateField(_("Task Date"), blank=True, null=True)
task_location = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
budget = models.FloatField(null=True)
task_description = models.CharField(max_length=1000, null=True)
task_image = models.ImageField(
null=True, blank=True, help_text='Optional.')
def __str__(self):
return str(self.user)
instead of using all() in your query use filter()
all() gives you all the entries in the table.
do something like this:
appointments = Appointment.objects.filter(user = request.user)
the left side "user" inside the filter must be a column in the Appointment model/table. you can pass multiple parameters inside the filter.
Yea it worked. but i had to create a one to one relatioship between appointment and User

Add new item in many to many field via api in Django

I'm calling an API to update the my liked_products many to many model in Django but, when calling the prod ID to add the item to the list, I get the error:
AttributeError at /api/customer/like_product/
'ReturnDict' object has no attribute 'liked_products'
Here is my API:
#csrf_exempt
def updated_liked_products(request):
customer = get_user(request)
if not customer:
return JsonResponse({'invalid token'})
customer_details = CustomerDetailSerializer(CustomerDetails.objects.get(
customer=customer)).data
customer_details.liked_products.add(request.data['prodId'])
customer_details.save()
return JsonResponse({"success": 'updated'})
Customer Details Model:
age = models.IntegerField(default="21", blank=True)
address = models.CharField(
default='', max_length=254, null=True, blank=True)
nick_name = models.CharField(
default='', max_length=254, blank=True)
average_order = models.FloatField(default="0.0", blank=True)
completed_orders = models.IntegerField(default="0", blank=True)
customer = models.ForeignKey(
Customer, on_delete=models.CASCADE)
customer_type = MultiSelectField(
choices=CUSTYPE, default=CUSTYPE, max_length=100)
current_selfie = models.ImageField(
upload_to='sefies/', blank=True, default='')
email_confirmed = models.BooleanField(default=False)
last_signin = models.DateTimeField(default=timezone.now)
liked_products = models.ManyToManyField('Product')
needs_help_with = MultiSelectField(
choices=CATEGORIES, max_length=1000, default='')
phone = models.CharField(
I am using Postman to update the data like this so I can see the liked product field but, cannot access it.:
You're having this error because you're trying to access liked_products attribute on a serialized data that is an instance of ReturnDict and not CustomerDetails.
It seems like there is not much point in the serializer usage in this API so you should be able to achieve what you want with just this:
#csrf_exempt
def updated_liked_products(request):
customer = get_user(request)
if not customer:
return JsonResponse({'invalid token'})
customer_details = CustomerDetails.objects.get(customer=customer)
customer_details.liked_products.add(request.data['prodId'])
return JsonResponse({"success": 'updated'})

Django - conditional foreign key

I have the following 4 models in my program - User, Brand, Agency and Creator.
User is a superset of Brand, Agency and Creator.
A user can be a brand, agency or creator. They cannot take on more than one role. Their role is defined by the accountType property. If they are unset (i.e. 0) then no formal connection exists.
How do I express this in my model?
User model
class User(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
email = models.EmailField(max_length=255, null=True, default=None)
password = models.CharField(max_length=255, null=True, default=None)
ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_id = models.ForeignKey(Brand)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)
class Meta:
verbose_name_plural = "Users"
def __str__(self):
return "%s" % self.email
Brand model
class Brand(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
brand = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)
class Meta:
verbose_name_plural = "Brands"
def __str__(self):
return "%s" % self.brand
Creator model
class Creator(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
first_name = models.CharField(max_length=255, null=True, default=None)
last_name = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
youtube_channel_username = models.CharField(max_length=255, null=True, default=None)
youtube_channel_url = models.CharField(max_length=255, null=True, default=None)
youtube_channel_title = models.CharField(max_length=255, null=True, default=None)
youtube_channel_description = models.CharField(max_length=255, null=True, default=None)
photo = models.CharField(max_length=255, null=True, default=None)
youtube_channel_start_date = models.CharField(max_length=255, null=True, default=None)
keywords = models.CharField(max_length=255, null=True, default=None)
no_of_subscribers = models.IntegerField(default=0)
no_of_videos = models.IntegerField(default=0)
no_of_views = models.IntegerField(default=0)
no_of_likes = models.IntegerField(default=0)
no_of_dislikes = models.IntegerField(default=0)
location = models.CharField(max_length=255, null=True, default=None)
avg_views = models.IntegerField(default=0)
GENDER_CHOICE_UNSET = 0
GENDER_CHOICE_MALE = 1
GENDER_CHOICE_FEMALE = 2
GENDER_CHOICES = (
(GENDER_CHOICE_UNSET, 'Unset'),
(GENDER_CHOICE_MALE, 'Male'),
(GENDER_CHOICE_FEMALE, 'Female'),
)
gender = models.IntegerField(choices=GENDER_CHOICES, default=GENDER_CHOICE_UNSET)
class Meta:
verbose_name_plural = "Creators"
def __str__(self):
return "%s %s" % (self.first_name,self.last_name)
Agency model
class Agency(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
agency = models.CharField(max_length=255, null=True, default=None)
email = models.EmailField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)
class Meta:
verbose_name_plural = "Agencies"
def __str__(self):
return "%s" % self.agency
Update:
So I've whittled it down to this bit here in the model:
ACCOUNT_CHOICE_UNSET = 0
ACCOUNT_CHOICE_BRAND = 1
ACCOUNT_CHOICE_CREATOR = 2
ACCOUNT_CHOICE_AGENCY = 3
ACCOUNT_CHOICES = (
(ACCOUNT_CHOICE_UNSET, 'Unset'),
(ACCOUNT_CHOICE_BRAND, 'Brand'),
(ACCOUNT_CHOICE_CREATOR, 'Creator'),
(ACCOUNT_CHOICE_AGENCY, 'Agency'),
)
account_type = models.IntegerField(choices=ACCOUNT_CHOICES, default=ACCOUNT_CHOICE_UNSET)
limit = models.Q(app_label='api', model='Brand') | \
models.Q(app_label='api', model='Creator') | \
models.Q(app_label='api', model='Agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')
If account_type = 1 then link to brand model
If account_type = 2 then link to creator model
If account_type = 3 then link to agency model
How do I accomplish this? Getting this error:
File "/Users/projects/adsoma-api/api/models.py", line 7, in <module>
class User(models.Model):
File "/Users/projects/adsoma-api/api/models.py", line 28, in User
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices(), related_name='user_content_type')
NameError: name 'get_content_type_choices' is not defined
Have you tried exploring Django's GenericForeignKey field?
class User(models.Model):
...
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=limit, related_name='user_content_type')
object_id = models.UUIDField()
content_object = GenericForeignKey('content_type', 'object_id')
You can access the User's brand/creator/agency by using the following notation:
User.objects.get(pk=1).content_object
This will be an instance of Brand/Creator/Agency as per the content_type.
https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey
Update based on your comment
Re 1: Using email:
class User(models.Model):
...
email = models.EmailField(max_length=255, unique=True)
limit = models.Q(app_label='your_app_label', model='brand') |
models.Q(app_label='your_app_label', model='creator') |
models.Q(app_label='your_app_label', model='agency')
content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_type_choices, related_name='user_content_type')
content_object = GenericForeignKey('content_type', 'email')
Note: Email can not be a nullable field anywhere if you follow this approach! Also this approach seems hacky/wrong since the email field is now declared in multiple places; and the value can change if you re-assign the content objects. It is much cleaner to link the GenericForeignKey using the discrete UUIDField on each of the other three models
Re 2: Using account_type field:
ContentType is expected to be a reference to a Django Model; therefore it requires choices that are Models and not integers.
The function of limit_choices_to is to perform a filtering such that all possible models are not surfaced as potential GenericForeignKey
class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
However, limit_choices_to does accept callables; so you can write a helper method that translates your account_type to the correct Model
I am not clear about how this transaltion should work; so I leave that to you.
Here is how I solve it, override the save method check your condition
tested on Django 3.2
CUSTOMER = [
('customer', 'customer'),
('supplier', 'supplier'),
]
class Customer(models.Model):
name = models.CharField(max_length=256, null=False, blank=False)
user_type = models.CharField(max_length=32, choices=CUSTOMER)
class SupplierOrder(models.Model):
price = models.FloatField(default=0)
supplier = models.ForeignKey(Customer, related_name='supplier', on_delete=models.CASCADE)
def save(self, *args, **kwargs):
supplier = get_object_or_404(Customer, id=self.supplier.id)
if supplier.user_type != 'supplier':
raise ValueError('selected user must be supplier')
super().save(*args, **kwargs)

Categories