Django Many Users to One model. A Model about the User - python

I'm trying to figure out how many users can be associated with one instance of a model.
I have a sports club project. There are many users (admin and staff) only one Club. I can't seem to form a many to one relationship with the User model.
I want to filter mainly by the club.
Say if 3 clubs use the project, each club would want to be separated by the club and not by the user.
Below is a simplified version of my models.
I've also tried to add the ForeignKey to the club and go the other way.
Class Club(models.model):
name = models.CharField(max_length=40, null=True)
Class User(AbstractBaseUser):
name = models.CharField(max_length=40, null=True)
club = models.ForeignKey(Club, on_delete=models.CASCADE)

Since there is just one club but various users, I believe your model should remain like this but on the user model you can assign different roles for different users in a club
Class User(AbstractBaseUser):
name = models.CharField(max_length=40, null=True)
club = models.ForeignKey(Club, on_delete=models.CASCADE)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)

You are defining your models appropriately. When you create the ForeignKey, each instance of the model that is being associated with (here your Club model) has access to the instances associating with it through a Manager object. You can define the "related_name" argument in the ForeignKey field definition so that your club objects have access to the users associated with them through a custom-defined name (rather than the default name):
Class Club(models.model):
name = models.CharField(max_length=40, null=True)
Class User(AbstractBaseUser):
name = models.CharField(max_length=40, null=True)
club = models.ForeignKey(Club, related_name="members", on_delete=models.CASCADE)
You can then access the related users with club.members.all assuming that "club" is the name of the club context object passed to the Template and "members" is the related_name of the User model's ForeignKey relation to Club. As a trivial example, if you wanted to list the members of a club, you could then do the following:
{% for member in club.members.all %}
<p>{{member.name}} is a member</p>
{% endfor %}
Check out this link for more on ForeignKey relations: https://docs.djangoproject.com/en/2.2/topics/db/queries/#following-relationships-backward

Related

Delete 2 model different objects which reference each other as foreign keys

We have two Django models:
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
usernmae = models.CharField(max_length=50)
active_project = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
I have a user with object (with id say 692). And this user created a project with id=12345, therefore these owner field will get have this particular referenced.
I want to delete that user. But it shows error that
delete on table "app_user" violates foreign key constraint
This is expected as on_delete=models.DO_NOTHING, was set. One way I found out was using on_delete=models.CASCADE.
Question: How should I go about deleting the user (692) without changing the model definition(having to re-run migration)?
Doing it manually by deleting the project first, leads to the same foreign-key error, as owner field is User object.
How to handle this mutual foreign key relationship while deleting, as deleting any one of those two throws the foreign-key exception?
Update
Some correction in the model definition username is the field name instead of usernmae (typo). And the foreignkey for project is Project not the User model.
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
username = models.CharField(max_length=50)
active_project = models.ForeignKey(Project, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
IF you really don't want to make a migration (any specific reason?) and if you are ok with doing this manually this time. Then you have two options:
Go into the admin panel and manually change the User field in the project instance to a different user or to NULL. Now you should be able to delete the User instance since it's not referred anymore into the project.
If that worked, you can then delete the project instane as well.
Curios if this will work, let me know!

Dynamic django choice field

I have 4 models: Products (the list of products: freezers, microwaves, tvs and pcs), ProductType (entertainment and home appliances), Credit (a credit is registered on each purchase) and PurchaseReason (the reason why the customer has bought the product).
The PurchaseReason depend on the productType, so the purchaseReason has a foreignKey field productType.
In addition, each credit has a product as foreignKey and a purchaseReason as foreignKey.
Also, I have the ProductReason field as a choice field in the credit model, and I want the options to be set dynamically based on the product field of the credit model.
I'm creating an API so I think this cant be handle with modelForms, but i'm not sure. The hard work would be with the serializers (DRF) and with the django-admin (specially this one because in my product the django admin plays an important role)
What would be the best approach to manage my models in Django?
Here are my models. In credit I'm not sure how to implemente the purchase reason:
class Credit(models.Model):
client = models.ForeignKey('clients.Client', on_delete=models.SET_NULL)
name = models.CharField(max_length=30, null=False, blank=True)
product = models.ForeignKey('product',on_delete=models.SET_NULL)
reason_purchase = models.ChoiceField(????)
class PurchaseReason(models.Model):
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
reason = models.CharField(max_length=30, null=False, blank=True)
class ProductType(models.Model):
name = models.CharField(max_length=30, null=False, blank=False)
class Product(models.Model):
model = models.CharField(max_length=30, default=None, null=True)
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
When we use the foreign key, we need to mention the model name of that particular model so that we can integrate that particular model in that model as a reference entity. Have a look at this example.
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
class Meta:
ordering = ['headline']
you've not mentioned the model name properly. it should be Product in place of 'product' in the Credit class, product field.
use this reference https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
i think you should be able to use the Foreignkey field properly after this. Although, if you can't, you can share the actual objective. i will help you to write the correct model.
Best wishes :)

Django - How to create many to one relation

In my application there is many-to-one relation, such as one teacher can teach more than one subject. So in admin panel I can't simulate it. Can't add more than one subject:
Here are my codes:
models.py:
class Subject(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=200)
credit = models.IntegerField()
class Teacher(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=100)
email = models.CharField(max_length=100, null=True)
chair = models.ForeignKey(Chair, on_delete=models.CASCADE)
academic_degree = models.CharField(max_length=100)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
You've got it reversed. ForeignKey is Many-to-One with Many being the instances of model where it is defined; you've declared ForeignKey on the Teacher model to Subject model, which means "many teachers can teach only a single subject" -- which should be the other way around.
So define the ForeignKey to the Teacher model on the Subject model. And also do the same for other similar ones.
You are doing it other way around
You should put the 'ForeighKey' relation in 'Subject' model instead of 'Teacher'
class Subject(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=200)
credit = models.IntegerField()
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
This is assuming there is only 1 teacher for a subject. Teacher can have multiple subjects. If there are many teachers for same subject then you need to use ManyToMany() relation.
Django has extremely great support for a attribute related to many other attribute. In your case a single subject could be taught by multiple teacher and multiple teacher can teach single subject. In order to define relationship like above you can leverage ManyToMany relation(this facilate many subject getting associated with single teacher). In case you need one to Many relationship you can use ManyToOne relation.
subject = models.ManyToManyField(subject)

Using a django model as a field for another model?

I have been tasked with creating Django Models for a hypothetical apartment booking application.
My question is: can I use a model that I've defined, as a field in another model?
For example, I will have one model called "Listing" that represents an apartment being listed.
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
I also want to have a "Booking" model that represents an apartment once someone has booked it. It will have the exact same info as a Listing, with the addition of the username of the person who booked it. So can I have my Booking model use Listing as a field? And then just have one extra field for the booker's username.
Any other tips/critiques are highly appreciated as I am a complete beginner at Django.
I'm not 100% sure what you mean by use Listing as a field
But to me, you should be looking at the different built-in model relationships that exist in Django.
In your particular case, you will probably want to use a One-to-One relationship like so,
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(models.Model):
listing= models.OneToOneField(
Listing,
on_delete=models.CASCADE,
)
username = models.Charfield()
Now if a user can book more than one apartment at a time, you'll be interested in a ForeignKey relationship like so,
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(models.Model):
listing= models.ForeignKey(
Listing,
on_delete=models.CASCADE,
)
username = models.Charfield()
Note that in both examples I used Charfield for the username, feel free to use whatever Django field you need.
The concept of a model as field is odd. What you can do is establish relationships between models, or to inherit one from the other. Given your situation, you can maybe inherit Booking from Listing:
The docs on this topic.
You'll have something like this:
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(Listing):
#your new fields

Django Extend Model with Optional Fields

I have a django model that looks something like
class Person(models.Model):
name = models.CharField(max_length=100)
favorite_color = models.CharField(max_length=100)
favorite_candy = models.CharField(max_length=100)
and I want to make a template model for it. Basically, I want a model that can have an arbitrary amount of Person's fields filled out. For instance, say I wanted to have a template for Person that likes chocolate - I'd say something like chocolate_template = PersonTemplate(favorite_color='chocolate') and if I wanted someone whose name is Gerald, I could say gerald_template = PersonTemplate(name='Gerald'). The thought is that I could use these template objects to later pre-fill a Person creation form.
My main question is an implementation question. It's totally possible for me to make a template like so
class PersonTemplate(models.Model):
name = models.CharField(max_length=100, blank=True)
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)
but the code is horrible in that I have to manually copy-paste the contents of the Person class. This means that if I change Person, I have to remember to update PersonTemplate. I was wondering if there's a prettier way to make a 'child' of a model where all of the fields are optional. Setting all of the fields of Person to blank=True and adding an isTemplate field is also a no-no because Person and PersonTemplate should be two different entities in the database. Any thoughts on this?
Yes of course :)
class PersonTemplate(Person):
field = models.CharField(max_length=100, blank=True)
Its mean you have every fields from Person and you can add more specific fields for PersonTemplate
class Person(models.Model):
Already extend from Model, its why you have access to created, modified, id, pk....
What is good its PersonTemplate 'extend' Person who 'extend' Model.
Since Django 1.10 you can overrride field like that :
class PersonTemplate(Person):
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)

Categories