i am trying to do permission for user where i defined my model like this
class UserInstances(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,blank=True,null=True,unique=False)
instance_name = models.CharField(max_length=150)
instance_size = models.PositiveIntegerField(default=0)
instance_objects = models.PositiveIntegerField(default=0)
instance_map = models.TextField()
instance_permission = models.ManyToManyField(User,related_name='instance_permission')
def __str__(self):
return f"{self.instance_name} instance for {self.user}"
API code
user = Token.objects.get(key=request.auth)
if UserInstances.objects.get(id=2).instance_permission.exists(user) :// for demonstration
print("access granted")
Can you tell me how to check if user exist or not in many to many field object
you can use
.values_list('{your field}', flat=True)
and then use
in python methode
or you can append users id in a list and then use
in python methode like this:
users = UserInstances.objects.get(id=2).instance_permission.all()
usres_list_id = []
for user in users:
usres_list_id.append(user.id)
if user_instance.id in users_id_list:
#do somethong
Many-to-many relationships can be queried using lookups across relationships, please refer to the Django documentation here.
Long story short, you can filter the UserInstances model and query for the users in instance_permission, i.e. using instance_permission__in.
Related
I have a built-in User table and a Note table associated with it by key.
class Note(models.Model):
header = models.CharField(max_length=100)
note_text = models.TextField()
data = models.DateField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
That is, a registered user may have several notes. How do I get all these notes from this particular user (who has now visited his page)? I need to get these notes in views.py.
I tried different ways, don't know how to do that.
Hope this answer finds you well ...
First, you already have a user object in your request. But, still you want to filter out notes for other users too, then do
get_user = User.objects.get(id=id) # For any random user
get_user = request.user # For authenticated user
After getting the user, you simply filter it with the Note model like this ...
get_notes = Note.objects.filter(user=get_user)
You are good to go!
How can I concatenate two different model query and order by a field that both models has like progress fields.
For example
models.py
class Gig(models.Model):
author= models.ForeignKey(User)
title = models.CharFields()
progress = models.IntegerField()
class Project(models.Model):
author= models.ForeignKey(User)
title = models.CharFields()
progress = models.IntegerField()
Can I do my view.py like this, for me to achieve it?
İf No, How can I achieve it?
views.py
def fetch_all_item(request):
gig = Gig.objects.filter(author_id = request.user.id)
project = Project.objects.filter(author_id = request.user.id)
total_item = (gig + project).order_by("progress")
return render(request, "all_product.html", {"item": total_item})
I am trying to join two query set from Gig and Project models then send it to frontend in an ordering form by a field name called progress.
You can let Python do the sorting for you, like:
from operator import attrgetter
def fetch_all_item(request):
gig = Gig.objects.filter(author=request.user)
project = Project.objects.filter(author=request.user)
total_item = sorted([*gig, *project], attrgetter('progress'))
return render(request, "all_product.html", {'item': total_item})
It might however be better to remodel this to a single model with a type field that disambiguates between a Gig and a Project.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
In general, such design when there are common fields is better accomplished by inheriting from some base class. E.g.:
class CommonActivity(models.Model):
# common fields for Project/Gig
author = models.ForeignKey(User)
title = models.CharFields()
progress = models.IntegerField()
class Gig(CommonActivity):
pass # or other fields related to Gig only
class Project(CommonActivity):
pass
Then if you want to query both - you query CommonActivity.
If remodel not possible - then filter via Python as #WillemVanOnsem suggested.
However such filtering will be way less efficient
I am learning by building and have a little FriendShip class. In one of my views, I want to filter the FriendShips such that my user is shown a list of all friendships he or she is involved in.
To give you an idea, something like this that has valid syntax:
relevant_friends_list = FriendShip.objects.filter(request.user.username == creator || request.user.username == friend)
But you can't just do that since friend and creator are user objects.
models.py
from django.contrib.auth.models import User
class FriendShip(models.Model):
created = models.DateTimeField(auto_now_add=True, editable=False)
creator = models.ForeignKey(User, related_name="friendship_creator_set")
friend = models.ForeignKey(User, related_name="friend_set")
def __str__(self):
return self.creator.username + " | " + self.friend.username
If I were to mimic the tutorial, I would add properties like creator_name = models.charField(...) and set that equal to User.username or something. But that sounds like I'm overthinking things, and it just feels like django would have a minimal-line solution. Thanks for your time
You are indeed overthinking. You can filter by model objects, and since you want an OR operation, you can use Q objects like so:
from django.db.models import Q
user = request.user
conditions = Q(creator=user) | Q(friend=user)
relevant_friends_list = FriendShip.objects.filter(conditions)
Note that request.user is only available inside a view where the request object is available.
I am using Django Rest Framework to provide API to a mobile app. I have two models, Order and User. Order has a foreign key relation to User.
For about 1% or so of all my order objects, the User field is null. I've been testing this behavior using cURL.
If I do a cURL without a user object, it tells me "This field is required".
If done with a wrong user object, it tells me that the object does not exist. Both of these are the intended and expected behaviors.
I'm trying to figure out how it is possible for some of the Order objects to be saved without a user field. Is there something I'm not taking into account?
My views:
class OrderList (generics.ListCreateAPIView):
model = Order
serializer_class = OrderSerializer
And serializer:
class OrderSerializer (serializers.ModelSerializer):
user = serializers.SlugRelatedField(slug_field = 'user')
partial = True
class Meta:
model = Order
Models:
class User (models.Model):
uid = models.CharField(max_length =200, unique=True)
class Order (models.Model):
uid = models.ForeignKey (User, related_name = "orders", verbose_name = "User",blank=True, null=True)
You could use two different ModelSerializer classes, one for creation, that makes sure, that an Order object can't be created without a related User and one for updating orders, that passes required=False to the related field's constructor, so that you still can save existing orders that haven't a related User.
Try adding default=None to your models.ForeignKey declaration. You could also just create an anonymous user in the users table and when the user isn't specified it could set the anonymous user instead.
I'm having trouble doing an aggregation query on a many-to-many related field.
Here are my models:
class SortedTagManager(models.Manager):
use_for_related_fields = True
def get_query_set(self):
orig_query_set = super(SortedTagManager, self).get_query_set()
# FIXME `used` is wrongly counted
return orig_query_set.distinct().annotate(
used=models.Count('users')).order_by('-used')
class Tag(models.Model):
content = models.CharField(max_length=32, unique=True)
creator = models.ForeignKey(User, related_name='tags_i_created')
users = models.ManyToManyField(User, through='TaggedNote',
related_name='tags_i_used')
objects_sorted_by_used = SortedTagManager()
class TaggedNote(models.Model):
"""Association table of both (Tag , Note) and (Tag, User)"""
note = models.ForeignKey(Note) # Note is what's tagged in my app
tag = models.ForeignKey(Tag)
tagged_by = models.ForeignKey(User)
class Meta:
unique_together = (('note', 'tag'),)
However, the value of the aggregated field used is only correct when the model is queried directly:
for t in Tag.objects.all(): print t.used # this works correctly
for t in user.tags_i_used.all(): print t.used #prints n^2 when it should give n
Would you please tell me what's wrong with it? Thanks in advance.
I have figured out what's wrong and how to fix it now :)
As stated in the Django doc:
Django interprets the first Manager defined in a class as the "default" Manager, and several parts of Django will use that Manager exclusively for that model.
In my case, I should make sure that SortedTagManager is the first Manager defined.
2.I should have count notes instead of users:
Count('notes', distinct=True)