If I had a One-To-Many relationship in Django, like the Django example at http://docs.djangoproject.com/en/dev/topics/db/models/#fields, A musician can have many albums, unique to that musician.
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
How would I go about implementing the following:
In Django, have 'Musicians' as a section to manage. When you go to manage musicians, you can edit the musician, or you can go on to the albums and manage the albums only for that musician. When you make a new album, the system automatically creates it for the musician you are on.
At the moment, you would have to manage albums individually from a huge list and choose the musician in the edit screen.
This is too complicated for the django admin as is, so either you explore the customization that the docs offers for you or you might consider not using the django admin at all and just write it as a part of your web app.
Check out http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adminsite-objects.
Admin inlines is one solution - http://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-objects - this will allow you to edit any Albums associated with the musician you are viewing or add a new one.
Related
Use case:
Want to let an admin create favourite relationships between users.
To do this, I am creating a model called Favourites.
class Favourite(models.Model):
user = models.ForeignKey(to=CustomUser, on_delete=models.CASCADE)
otheruser = models.IntegerField()
However, both user and otherusers are both objects in CustomUsers. In the admin console, when adding a favourite I get a list of users, but I do not get a list of other users obviously.
What model field can I use so that when adding a favourite I get a list of users, and when choosing the otheruser that is also a list of users?
It makes more sense here to add a ManyToManyField [Django-doc] in your CustomUser, so:
class CustomUser(models.Model):
# …
favorites = models.ManyToManyField(
'self',
symmetrical=False,
related_name='fans'
)
I have a Django application where registered users can add, through an input form, details of performances of their music ensemble. This application also has a a section for composers, where they add their own composition. I'm using a custom user model, with profiles linked to user accounts:
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="email", unique=True, max_length=255)
first_name = models.CharField(max_length=30, blank=True, null=True)
[...]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
[...]
This is my 'composition' model:
class Composition(models.Model):
title = models.CharField(max_length=120) # max_length = required
composer = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
[...]
And this is my 'performance' model. The performance information links to the piece performed (performed):
class Performance(models.Model):
performed = models.ManyToManyField(Composition, blank=True)
[...]
So far, so good. Now, I'd like the performers to be able to add pieces by composers who are not (yet) registered to the website. Let's say that the performer performed a piece by John Lennon and is adding information about that performance. So, the performer will need to be able to add both John Lennon, his composition, and link the two.
The most important bit is: if the ghost of John Lennon tomorrow wants to register to the website, the administrator of the website will need to be able to easily link the compositions already added by the performers to John Lennon's newly created account. Is that possible? I suppose the key to solving this issue is changing composer = models.ForeignKey(settings.AUTH_USER_MODEL... with something else, i.e. using a intermediary model. Any suggestion will be greatly appreciated.
There are different ways to do this, you should choose one based on your taste:
When you know that the actual user is registered, just delete the old, fake user referred in the composition and replace it with the actual user.
Create a new model named something like Artist and change the composer relationship to refer to the Artist model. then, link the Artist model to the actual user with a nullable foreign key.
Let's say I've got 2 models
class Person(models.Model):
name = models.CharField(max_length=50)
class Language(models.Model):
person = models.ForeignKey(
Person, related_name='prs', on_delete=models.CASCADE)
name = models.CharField(max_length=50)
I want to be able to access all persons languages like that -> person/{person_id}/language
and to access and edit specific language like that -> person/{person_id}/language/{language_id}
In this scenario, you can use drf-nested-routers package.
As you are new to DRF, I know there is chance that you haven't seen routers and ModelViewSet yet, so I would recommend you to go through that first. Here is the link which explains this flow.
My user object with rest framework has an avatar_id and a cover_id. But Instead of displaying that to the API, I want it to be the actual avatar URL and cover URL already.
My User model:
avatar_id = models.IntegerField()
cover_id = models.IntegerField()
My UserAvatar model:
id = models.IntegerField(primary_key=True)
user_id = models.IntegerField()
file_id = models.IntegerField()
My Files model:
id = models.IntegerField(primary_key=True)
filename = models.CharField(max_length=255)
Same concept with UserCover.
How do I remove the avatar_id from the results of /users/ and add a avatar field with the actual avatar filename?
I'm not sure I understand your question correctly, but here what I think the problems are. Reading your question, I assumed that you are a beginner, so I answered as such. Sorry if it's not the case.
You don't need to add the id fields, it's done automatically by Django because all tables need a primary key. You define a PK only when you need to name it something else than 'id'.
You should really read the Django tutorial which explains how to define models. User.cover_id and UserAvatar.file_id should be defined as ForeignKey. If you don't know what a foreign key is, then stop playing with Django and read a database tutorial before.
There's already a model and a set of classes to manage your users in Django. You should use them. For example, a "user profile" is the right way to extend the user model.
If you force the users to choose one avatar in a set of predefined avatars, then what you want to do is ok. If the users can choose any avatar (upload), then you should use OneToOneField or put it directly in the user model (or profile).
I don't know what is a UserCover, but here's what your models could look like:
from django.contrib.auth.models import User
class UserProfile(models.Model):
# Link to Django normal User (name, email, pass)
user = models.ForeignKey(User, unique=True)
# Any information that a user needs, like cover, wathever that is, age, sexe, etc.
avatar = models.CharField(max_length=255)
Or like this if a will be reused often :
class Avatar(models.Model):
# name = ...
# description = ...
path = models.CharField(max_length=255)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
avatar = models.ForeignKey(Avatar, unique=True)
# other data
I have 3 models as such:
class Customer (models.Model):
name = models.CharField (max_length = 20)
class Vehicle (models.Model):
make = models.CharField (max_length = 20)
customer = models.ForeignKey(Customer)
class Appointment (models.Model):
customer = models.ForeignKey (Customer)
vehicle = models.ForeignKey (Vehicle)
In the Appointment admin site, it currently shows me two dropdown lists, one showing all customers and the other showing all vehicles.
I want to implement it such that I first pick a customer, and then the second dropdown list is populated with a list of vehicles the customer owns. I know how to do this in a standard template with jQuery, but I can't find any documentation about how to do this in the admin site.
https://github.com/digi604/django-smart-selects
EDIT: There's also a small app which provides a widget that you can use in django admin, and which doesn't require changes to the model (ChainedForeignKey etc.).
https://github.com/runekaagaard/django-admin-flexselect