I have a model:
class Rent(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
bikes = models.ManyToManyField(Bike)
when I create a new rent in the admin site, I would like to exclude the bikes that have the value of 1 for their status integer field from showing in the list to choose from. Is this possible?
Thanks
I am not sure if you can do that from the Admin site. probably you cannot. But you can do it from views. just select the model objects you need with query and pass it into the field. I am attaching a ell explained similar scenario. condition your query and add those objects.
Adding many to many fields based on condition
You can customize the admin form. Here is a discussion of how to filter your form choices.
Thank you all! I figured it out, the problem was that the limit_choices_to doesn't work when I change the filter to inline and I found others with the same problem, so I just changed it to filter_horizontal and now it works as it should
Related
I want to model a schema for an award function in django. I have a User model, a show model and an award model. A user can get one award for a show. I can simply say User 'aaa' gets award 'bbb'. but then that award cannot be associated with other user for another show.
I think there is three way modeling required for User, show and Award. Is there any sophisticated way of doing it? I know about 'through' but dont think this can be a good tool here. If it is could you please guide me how to?
You can have an extra model, I will call it UserAward.
class UserAward(models.Model):
user = models.ForeignKey(User)
award = models.ForeignKey(Award)
show = models.ForeignKey(Show)
When I try to enforce two unique constraints only later one stays.
I wanted to get a list of objects associated to model A by ManyToMany with model B, e.g. diners (A) confirmed to attend a meal(B). But I'm not sure what getter I should use. I actually wanted to do this to show the associated objects in the admin panel. The method included beneath was one failed attempt I made.
class Meal(models.Model):
diners = models.ManyToManyField(User, through='Attendance', related_name="eating", blank=True)
def diners(self):
return self.eating
Can you help?
Thanks
As ilvar suggested, remove diners method and use self.diners.all() to get objects inside Meal methods. related_name='eating' is for fetching attended meals of a user, reversely.
I arrived at this page with the same problem as OP. I ended up simply removing the reference to the ManyToMany field in list_display in my admin model. The result: on the admin page for that app, under the ManyToMany field name, appeared a nicely formatted multi-selection list widget with the possible values for my ManyToMany relationship shown.
So the solution was to remove the reference in list_display and let Django handle it. This is with Django 1.4.3.
I want to add, some fields depending on others. I have city and country model. I can include country as foreign key in city model. And then if I will add both city and country in another model ( say content) then will it be just like dependent selectboxes? like cities will be shown based on selected country via ajax? If not then what is correct way? and also is there a way to add city on the spot while adding main content data if city is not already on list?
So are above possible by using django admin or is it that django don't give? If not then how can it be done in django autogenerated admin?
You can do exactly what you ask using django-smart-selects
Hope that helps...
I can include country as foreign key in city model
This seems like a good idea.
And then if I will add both city and country in another model ( say content) then will it be just like dependent selectboxes? like cities will be shown based on selected country via ajax?
No, it will not get filtered automatically, you will need to write that code yourself. Both in admin and on frontend.
and also is there a way to add city on the spot while adding main content data if city is not already on list?
You will get this in the admin area.
Go ahead and start doing it, and when you run into specific problems, post them here if you can't solve it. Also read the Django docs, it is pretty elaborate on the topic of models.
I'm trying to use Django's annotate feature to add the count of a related model to a queryset. However, I don't want a full count of related objects, I only want to count the active ones (i.e., "is_active=True"). I can't figure out how to filter down the count.
The (simplified) relevant models:
class Post(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=80)
body = models.TextField()
class Comment(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
comment_body = models.CharField(max_length=80)
is_active = models.BooleanField(default=True)
In a view, I'm trying to annotate a queryset:
queryset=Post.objects.all().annotate(num_comments=Count('comment', distinct=True))
The above counts all the comments related to a post, whereas I only want to count the "is_active" ones. Google and the Django docs aren't helping me here. Has anyone had and solved this problem?
You just need to filter on is_active before doing the annotation:
Post.objects.filter(comment__is_active=True).annotate(num_comments=Count('comment'))
See the explanation here.
This is how I had to "annotate" the number of active comments on my Post queryset:
Post.objects.extra(select={"num_comments":
"""
SELECT COUNT(myapp_comment.id) FROM myapp_reply
WHERE myapp_comment.is_active='1' AND
myapp_comment.post_id = myapp_post.id
"""
},)
Not pretty, but it works. As I mentioned in a comment above, it wasn't possible to use the built-in aggregation function annotate() for this, since that counted all related comments and I only wanted to count the active related comments.
Daniel's solution didn't work, because it filtered out Posts which had no comments. I don't want to filter out any Posts, just inactive comments.
If anyone has a better solution, I will gladly up-vote and best-answer you!
There is two variants based on what database you are using. If you use MySQL the solution is simple and elegant:
Post.objects.annotate(num_comments=Sum('comment.is_active'))
This works because in database boolean fields are integers and True is 1, False is 0.
But this works ONLY in MySQL and works ONLY for boolean fields. The more general way to do the job which works on all databases and can do more complex checks is using a little SQL inserted a little 'hacky':
Post.objects.annotate(num_comments=Count('comment',
field='CASE WHEN myapp_comment.is_active THEN 1 END'))
I have the same problem in my personal blog, and that was the solution. I write a blog post for that. http://venelin.sytes.net/blog/django/filtrirane-na-agregirash-count-v-django/. It's on bulgarian but my site uses google translation. The translation is not very good but may help to understand why this works.
How do I travel through multiple foreign keys in Django? I've tried everything I can think of from the django docs, but I'm obviously missed something (extreme newbie). I have models for scientists, experiments, and theories.
If I want to look at a particular Theory (let's call it 'relativity') and get a list of all of the emails of scientists working on it (kept in the normal django user model), how do I do this?
class Experiment(models.Model)
experimenter = models.ForeignKey(Scientist)
theory = models.ForeignKey(Theory)
class Theory(models.Model)
name = models.CharField(max_length=100)
class Scientist(models.Model)
user = models.ForeignKey(User, unique=True)
institution = models.CharField(max_length=20, null=True, blank=True)
These are simplified versions of my models that I rewrote, so there are probably some errors in it, but the relationships are correct.
I've tried every kind of combinations of select_related(), get(), filter() but can't figure it out. Thanks in advance for your help!
User.objects.filter(scientist__experiment__theory__name=u'relativity')
Take a look at the Django documentation section about Lookups that span relationships. The net takeaway is:
To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want.
Ignacio's answer shows an example of using the double underscores on field names to span a relationship.
The other relevant portion of Django's documentation would be the Related objects section. Relationships in Django are asymmetrical in the way they are accessed. Forward/normal relationships are accessed as attributes of the models. Backward relationships are accessed:
Django also creates API accessors for the "other" side of the relationship -- the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute: b.entry_set.all().