django manytoone other side - django

I have a django webapp. I have something like this set up:
class Doc(models.Model)
invoice = models.ForeignKey(Invoice, null=True, on_delete=models.SET_NULL, blank=True)
class Invoice(models.Model)
#bla bla bla
Can I somehow create a form element that would stand for invoice.doc_set.all() ? I want it to be I want it to be a multiple select element. I know I dont want Inline formsets. What I want to see in django admin on Invoice side --> simple Multiple select element with all the instances that can be selected. When selected and saved the particular invoice will become the foreign key instance to them...

You could use a ModelMultipleChoiceField.
https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelmultiplechoicefield
But I don't think that the admin can manage this type of functionality out of the box. You will probably need to extends the admin form and set the FK by yourself.

Related

Wagtail: Limit choice dynamically based on current object

How can I limit the choices for the districtobject field in wagtail admin?
class DistrictPage(Page):
districtobject = models.ForeignKey(DistrictTranslated, on_delete=models.SET_NULL, null=True, blank=True)
I know that I can use "limit_choices_to" for basic limitations with Q. But I want to use a more dynamic approach which allows me to use the "content" of the current object. (Like self.attribute ... etc)
For example:
def my_limit_function(self):
1. get parent page
2. read date from parent page and extract this information for a filter query
I don't think you can do that in the Page class definition. I think you are going to need to customize the page form as in this example in the documentation. The values can be set in the form __init__.py. Don't forget that there won't be a parent page until your page is saved for the first time.

User model with static set of related models

Say I have a User model in django and I want to add some achievements to users. So I've created an Achieve model:
class Achive:
type = ....
value = ....
status = BooleanField(default=False)
I want all those achieves be a static set of models for every user (20 instances, for example) with ability to delete old and create new achieves. The problem is how to do it. Expected flow is:
1) user granted to use achievement system;
2) user got all those achieves (in admin panel shows like a table);
3) in admin panel per user I can change status of every achieve (affects only on edited user);
4) if new Achieve instance is created — add to all users who have achievements;
5) if existed Achieve instance has been deleted — remove from all users;
Solutions with I came up:
1) use Achieve model with jsonfield. store achieves in json like dictionary, use custom widget for admin panel to show checkboxes to change status). But where to store global set of achievements to create new/delete old ones? how to manage it?
2) use many to many field to Achieve and Achieve model without status. Why: if relation between User ← → Achieve exists, that means that user earn an achieve.
Both solutions I don't really like so hope for your advice.
P.S. sqlite is used as db and not allowed to use another (like mongo, etc.)
Thanks in advance!
What you want is a ManyToMany relationship between Achieve and User, but with the ability to store extra data on the relationship (the status for example).
With a normal ManyToManyField on a Model, Django actually creates an intermediate model to store the relationships in the database. By adding a through argument to your ManyToManyField, you can specify the intermediate model used for the relationship and store extra data with the relationship, as documented here:
class Goal(models.Model):
type = ...
value = ...
achievers = models.ManyToManyField(to=User, through='Achievement', related_name='goals')
class Achievement(models.Model):
status = models.BooleanField()
date_reached = models.DateField(null=True)
goal = models.ForeignKey(to=Goal, on_delete=models.CASCADE)
achiever = models.ForeignKey(to=User, on_delete=models.CASCADE)
then you can create and query the relationships like this, assuming you have a user and a goal:
achievement = Achievement.objects.create(status=True, date_reached=date(2018, 10, 12), achiever=user, goal=goal)
user.goals.filter(achievement__status=True) # gives the achieved goals of a user
goal.achievers.filter(achievement__status=True) # gives the users that achieved a goal

How to create models directly for OneToOne Relationships in Django

As far as I read, I can create Items in the Django Shell and in the admin panel after some configuration.
But what I want is a "Subitem" of an "Item" that is created directly every time I create an "Item".
How it is:
Item is created via admin, needs "Upvote" and "Downvote" subitems to be created too manually.
How do I change Django to directly create Upvote and Downvote for me?
Thank you!
Instead of adding and creating subitems each time an Item is created, I just added the "Downvotes" as an IntegerField.
You just have to mention it when you are creating the model.
Suppose you have a Item model like this -
class Item(models.Model):
item_title = models.CharField(blank=True, null=True)
and then If you want one to one field then the code will be like
class SubItem(models.Model):
item = models.OneToOneField(Item, on_delete=models.CASCADE)
It will create subitem when you create Item. To access it you can directly access with dot notation. Suppose you have an SubItem object sub_item_obj then corresponding sub item is sub_item_obj.item

Django model ManytoMany getters

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.

How can I store many Django model types in a database and access them as an object?

I have the following Django models:
Bar, Bistro and Restaurant
Each of the above establishment has their own menu items, for instance:
Bar
Burger
Fries
...
Bistro
Pasta
Pizza
...
Restaurant
Duck
Wings
...
I have different type of images in my home page, a main banner, left side bar and right side bar. Each of those images will have links to menu items across the Bar, Bistro and Restaurant. I'm currently hard-coding the urls for each of those images in the admin:
class Image(models.Model):
alt_name = models.CharField
source = models.ImageField
url = models.CharField
The above is working fine but if one of the menu item changes, I will have to go back to the admin and re-write the new url. I'm thinking of improving my admin to make it look like the following:
Selecting the appropriate establishment will populate the proper menu items. In the backend, the database will store a string corresponding to the type of establishment along with a primary key of a menu item related to that establishment. I need the establishment association because the menu items are stored in their own tables(BarMenuItem, BistroMenuItem and RestaurantMenuItem).
Given a string Bistro, is it possible to retrieve its corresponding model of the same name in Django? I believe I might have gone overboard with the above solution, let me know of your thoughts if you have any suggestions.
Given a string Bistro, is it possible to retrieve its corresponding model of the same name in Django?
Yes.
model = ContentType.objects.get(model='Bistro').model_class()
http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/