django admin how to manipulate OneToMany related objects(not just inline) - django

I have 2 models.
One has a foreign key to another.
Say:
class Organization(models.Model):
title = models.CharField(max_length=300)
class User(models.Model):
name = models.CharField(max_length=300)
organization = models.ForeignKey(Organization)
I want to show all users who work in current organization in organizationAdmin, like a list of change links.
It should be possible
to add new user
to select existing user(no related to current organization) and set his organization to current
No need to edit them inline
Just like permissions in userAdmin + adding and changing them
Is there any ready solution? Not to make forms by hands

You can do that with exclude:
class UserInline(admin.TabularInline):
model = User
exclude = ['name', 'other_fields']
Or you can use ManyToMany relation:
class User(models.Model):
name = models.CharField(max_length=300)
class Organization(model.Model):
title = models.CharField(max_length=300)
users = models.ManyToManyField(User)

Related

Django admin: reverse select foreign keys

I want to add pre-existing foreignkey items from the parent's admin. I have a "Bundle" model to hold "Product" items; many-to-one/foreignkey:
models.py
class Bundle(models.Model):
title = models.CharField(max_length=300)
class Product(models.Model):
title = models.CharField(max_length=300)
bundle = models.ForeignKey(
'Bundle',
on_delete=models.CASCADE,
null=True,
blank=True,
)
Below, I used StackedInline but this is for creating new products with a form:
admin.py
class ProductInline(admin.StackedInline):
model = Product
#admin.register(Bundle)
class BundleAdmin(admin.ModelAdmin):
inlines = [
ProductInline,
]
Instead, I want to repeatedly add existing products from a dropdown/search in the Bundle section of admin. So, I make a Bundle and then add a series of Products from a dropdown / with a search.
Thanks in advance.
For you requirement, you can use ManyToManyField in Bundle model instead of ForeignKey in Product model.
Check below code.
class Bundle(models.Model):
title = models.CharField(max_length=255)
product = models.ManyToManyField('Product')
class Product(models.Model):
title = models.CharField(max_length=255)
Then you can register admin interfaces:
admin.site.register(Bundle)
admin.site.register(Product)
Then you can add series of Product from a dropdown/search.

Setting a Django ForeignKey to multiple models

I have a simple model called WebProfile that stores a webpage URL and its title. This model has a ForeignKey to a Student model, which allows me to store the student's bookmarks.
I would like to reuse this model to also store bookmarks saved by teachers. What is the best way to have the owner ForeignKey point to either a Student or Teacher?
Note: in my actual use case, the target model classes are conceptually very different and do not share any common fields other than the WebProfile links.
class Student(models.Model):
...
class Teacher(models.Model):
...
class WebProfile(models.Model):
title = models.CharField(max_length=50)
link = models.URLField()
owner = models.ForeignKey('Student', on_delete=models.CASCADE, related_name="bookmarks")
If Teacher and Student are related to the User model you could change the ForeignKey in WebProfile to be related to the User model instead.
From there you can then workout when you get a WebProfile object whether the user is a Student or Teacher.
I was able to solve the problem by using Generic Relations as described in Django documentation
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class WebProfile(models.Model):
title = models.CharField(max_length=50)
link = models.URLField()
owner_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
owner_id = models.PositiveIntegerField()
owner = GenericForeignKey('owner_type', 'owner_id')

Get all related field in Django model

I am struggling to understand how one-to-many and many-to-many relation works in Django model. My schema looks something like this so far, I am open for suggestions to make it better.
A many-to-many relation between users and team. Also, there will be schedules that belong to a particular user of a team.
This is how my model looks like so far,
class Team(models.Model):
tid = models.AutoField(primary_key=True)
team_name = models.CharField(max_length=30)
manager_name = models.CharField(max_length=30)
class Schedule(models.Model):
sid = models.AutoField(primary_key=True)
user = models.OneToOneField(User)
date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
pay_rate = models.CharField(max_length=30)
location = models.CharField(max_length=50)
class BelongsTo(models.Model):
bid = models.AutoField(primary_key=True)
user = models.OneToOneField(User)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE)
Question: I want to get the information of each user, what are their schedules and which team each schedule belongs to. How would I to do it? I have tried BelongsTo.objects.select_related().all(), but it is not working for me.
Note: I am open for suggestions, if something is wrong with my schema or model or the approach, please let me know.
BelongsTo is seems like utility table.So
BelongsTo.objects.all().values('user', 'team__team_name', 'schedule')
Your schema looks almost right, but I would modify it a little bit. In particular, I will change how Schedule is implemented. Instead of having a sid in the User Belongs To join-table, I would include the user and team in the Schedule table as foreign keys.
This is how the Django models should then look like:
class User(models.Model):
username = models.CharField(max_length = 200)
# put other fields like password etc. here
class Team(models.Model):
team_name = models.CharField(max_length=30)
manager_name = models.CharField(max_length=30)
user = models.ManyToManyField("User")
class Schedule(models.Model):
user = models.ForeignKey("User")
team = models.ForeignKey("Team")
date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
pay_rate = models.CharField(max_length=30)
location = models.CharField(max_length=50)
Note the following:
You don't need to have a primary key field in the models because Django adds a primary key field called pk or id automatically.
Note the absence of the User Belongs To model. Django implements join-tables like User Belongs To automatically when you use a ManyToManyField. See the Django docs on many-to-many relationships.
You also don't need on_delete = models.CASCADE on ForeignKey fields, because this is the default behavior.
To see how to get information about users, teams and schedule from this configuration of models, consult the Django documentation on making db queries. It's quite easy.

Model relationship in Django

I have a model for conversations between two users.
class Conversation(models.Model):
users = models.ManyToManyField(User)
recipient1_pk = models.CharField(max_length=100)
recipient2_pk = models.CharField(max_length=100)
And I have a child model for messages. I'd to include a Boolean field that would allow each user to toggle the visibility of the conversation. BUT I don't want this to affect the conversation for the other user so I can't just add it to the conversation model. Is there an efficient way for me to add a boolean field for each user to do this whilst still sharing the same conversation model?
Have a look at adding extra fields to your ManyToManyField via the through parameter:
class Conversation(models.Model):
users = models.ManyToManyField(User, through='ConversationPreferences')
recipient1_pk = models.CharField(max_length=100)
recipient2_pk = models.CharField(max_length=100)
class ConversationPreferences(models.Model):
user = models.ForeignKey(User)
conversation = models.ForeignKey(Conversation)
visibility = models.BooleanField()

How can I show a ManyToManyField value filtered on the basis of ForeignKey while editing an django model object?

I have four models in my models.py which are:
models.py
class Course(models.Model):
course_code = models.CharField(max_length=100,unique=True)
title = models.CharField(max_length=200)
short = models.CharField(max_length=50)
elective_group = models.CharField(max_length=100)
class Unit(models.Model):
title = models.CharField(max_length=100)
short = models.CharField(max_length=50)
course = models.ForeignKey(Course)
class Pattern(models.Model):
pattern_name = models.CharField(max_length=200)
class ExamSchedule(models.Model):
exam_date = models.DateTimeField()
course = models.ForeignKey(Course)
pattern = models.ForeignKey(Pattern)
**units = models.ManyToManyField(Units)**
I have all these models register with admin site, so that I can use admin functionality for these models.
My problem is when a user creates or edits a ExamSchedule object, I want the units(field) multivalue widget should contains only those values that are associated with a course as every course can have multiple units. So if user creates an Examschedule object and after selecting a course from dropdown the unit widget should only contains those units that related to the course selected.
Thanks
I have used this django plugin to do this exact thing in the admin sections. I believe it also works in the front end as well:
https://github.com/digi604/django-smart-selects