I created a Company in my django app, two or more person can login with the same company. I want to show the data of one user of the company to the other user of the company.
To simplify: If user1 of a company creates an object, then it should be visible to all the users of that company
Models.py
class User(AbstractUser):
is_employee = models.BooleanField(default=False)
is_client = models.BooleanField(default=False)
class Company(models.Model):
company_name = models.CharField(max_length=255, default=0)
company_email = models.EmailField(max_length=255, default=0)
company_phone = models.CharField(max_length=255, default=0)
def __str__ (self):
return self.company_name
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='comapany_owner')
def __str__ (self):
return self.user.username
class Product(models.Model):
product_name = models.CharField(max_length=255, default=0)
product_priceperunit = models.IntegerField(default=0)
product_owner = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='product_owner')
Views.py
#method_decorator([login_required, employee_required], name='dispatch')
class ProductsTableView(ListView):
model = Product
context_object_name = 'product'
template_name = 'packsapp/employee/employeeProductsTable.html'
def get_queryset (self):
queryset = Product.objects.filter(product_owner=self.request.user.employee)
return queryset
Here I am extracting the data by employee. How can I modify the query to give the data of all the employee of the same company ??
If that means that the product_owner of that Product belongs to the same company as the compnay of that employee, we can filter with:
#method_decorator([login_required, employee_required], name='dispatch')
class ProductsTableView(ListView):
# ...
def get_queryset (self):
return Product.objects.filter(
product_owner__company=self.request.user.employee.company
)
Related
I'm doing a cookbook app, which help users find meal thay can do with their ingridients. I'm using Django RestFramework, and i need to return list of avaliable meals that user can do, but don't know how to do search by ingridients
My models.py:
#models.py
class Meal(models.Model):
name = models.CharField(max_length=250)
description = models.TextField(blank=True, null=True)
recipe = models.TextField()
is_published = models.BooleanField(default=False)
category = ForeignKey('Category', on_delete=models.CASCADE, null=True)
user = ForeignKey(User, verbose_name='User', on_delete= models.CASCADE)
difficulty = ForeignKey('Difficulty', on_delete=models.PROTECT, null=True)
ingridients = models.ManyToManyField('Ingridient')
class Ingridient(models.Model):
name = models.CharField(max_length=100, db_index=True)
ico = models.ImageField(upload_to="photos/%Y/%m/%d/", blank=True, null=True)
category = ForeignKey('CategoryIngridients', on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
class CookBookUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
ingridients = models.ManyToManyField('Ingridient')
serializer.py
class MealSerializer(serializers.ModelSerializer):
class Meta:
model = Meal
fields = "__all__"
views.py
class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
serializer_class = MealSerializer
def get_queryset(self):
return Meal.objects.filter(ingridients=CookBookUser.objects.filter(user_id = self.request.user.id).ingridients)
CraftWithUsersIngridientsListAPIView isn't working and I get AttributeError 'QuerySet' object has no attribute 'ingridients', can someone help fix this?
I tried building different serializer but it doesn't help
class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
serializer_class = MealSerializer
def get_queryset(self):
user_ingredients = CookBookUser.objects.get(user=self.request.user).ingredients.all()
return Meal.objects.filter(ingredients__in=user_ingredients)
This way, you first get the CookBookUser instance for the current user, then get all of their ingredients, and finally, filter the Meal objects that contain those ingredients. The __in query lookup is used to check if the meal ingredients are in the user's ingredients.
My models:
class Ingredient(models.Model):
BASE_UNIT_CHOICES = [("g", "Grams"), ("ml", "Mililiters")]
CURRENCY_CHOICES = [("USD", "US Dollars"), ("EUR", "Euro")]
ingredient_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
base_unit = models.CharField(max_length=2, choices=BASE_UNIT_CHOICES)
cost_per_base_unit = models.FloatField()
currency = models.CharField(
max_length=3, choices=CURRENCY_CHOICES, default="EUR")
def __str__(self):
return self.name
class RecipeIngredient(models.Model):
quantity = models.FloatField()
ingredient_id = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
def __str__(self):
return f"{self.quantity} / {self.ingredient_id}"
class Recipe(models.Model):
recipe_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
ingredients = models.ManyToManyField(RecipeIngredient)
date_created = models.DateTimeField('Date Created')
def __str__(self):
return f"{self.name}, {self.ingredients}"
When I use the admin page, it has this + button that allows me to create new ingredient/quantity combinations
like this
But when I try to use it from a form in my code it looks like
this
Here is my form code:
class AddRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'ingredients', 'date_created']
You should write the 'widgets' for each field in you Form that need configuration.
Check the documentation 'Widgets in forms', or even, you can define your own Widgets.
I am following the example in the documentation: https://docs.djangoproject.com/en/3.2/topics/db/models/#extra-fields-on-many-to-many-relationships
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
In this case, given a Person object, how can I access all the groups that Person is in?
You access these with:
Group.objects.filter(members=my_person_object)
I'm trying to create a shopping cart model, I've created the Order Model, OrderItem model and Also the Item model. Although I find it difficult to link the order it model to the order in the API view.
here's the Model
class Pizza(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60)
desc = models.CharField(max_length=150)
price = models.IntegerField()
url = models.CharField(max_length=250)
def __str__(self):
return self.name
class OrderItem(models.Model):
id = models.AutoField(primary_key=True)
product = models.ForeignKey("Pizza", on_delete=models.CASCADE, null=True)
date_added = models.DateTimeField(auto_now=True)
date_ordered = models.DateTimeField(null=True)
amount = models.IntegerField(null=True)
def __str__(self):
return self.product.name
class Order(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60)
email = models.CharField(max_length=150)
address = models.CharField(max_length=150)
total = models.IntegerField()
created_at = models.DateTimeField(default=timezone.now)
items = models.ManyToManyField(OrderItem)
def __str__(self):
return self.name
//The viewset
class OrderViewSet(viewsets.HyperlinkedModelSerializer):
# permission_classes = [IsPostOrIsAuthenticated,]
serializer_class = OrderSerializer
queryset = Order.objects.all().order_by('-created_at')
Currently, I cant display the amount attribute of the order item in my API, It just shows the id and Also the link to the individual orderitem in an order
I think for cart you can use external fields on relations between Order and Pizza. Documentation about this here
Your models looks like:
class Pizza(models.Model):
name = models.CharField(max_length=60)
desc = models.CharField(max_length=150)
price = models.IntegerField()
url = models.CharField(max_length=250)
def __str__(self):
return self.name
class Order(models.Model):
name = models.CharField(max_length=60)
email = models.CharField(max_length=150)
address = models.CharField(max_length=150)
total = models.IntegerField()
created_at = models.DateTimeField(auto_now=True)
items = models.ManyToManyField(Pizza, through='OrderItem')
def __str__(self):
return self.name
class OrderItem(models.Model):
product = models.ForeignKey('Pizza', on_delete=models.CASCADE, null=True)
order = models.ForeignKey('Order', on_delete=models.CASCADE, null=True)
date_added = models.DateTimeField(auto_now=True)
date_ordered = models.DateTimeField(null=True)
amount = models.IntegerField(null=True)
def __str__(self):
return self.product.name
Example, how you can get dict of items amount in order:
order = Order.objects.filter('-created_at').first() // get last order
cart = {item.pk: item.amount for item in order.items}
I want to have a form which only offers the user to post a question for a project he is participating in.
models.py:
class Project(models.Model):
project_name = models.CharField(max_length=255, unique=True, blank=False)
def __str__(self):
return str(self.project_name)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
project = models.ManyToManyField(Project)
def __str__(self):
return str(self.user)
class Question(models.Model):
title = models.CharField(max_length=255, blank=False)
content = tinymce_models.HTMLField(blank=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
...
def __str__(self):
return str(self.title)
class QuestionForm(ModelForm):
class Meta:
model = Question
fields = ['title', 'content', 'project']
in views.py:
form = QuestionForm()
form.fields["project"].queryset = Project.objects.filter(project_name__in=request.user.profile.project.all())
But somehow the result of the query always stays empty.
Does somebody maybe have an idea what I am missing?
Your query is over complicated. You should just use the user's projects directly:
form.fields["project"].queryset = request.user.profile.project.all())