One membership for each user for each club - python

I'm creating models to manage clients and sports centers. Each customer can be enrolled in several centers only once of course. how should i proceed for this?
class Membership(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='memberships')
club = models.ForeignKey(Club, on_delete=models.CASCADE, related_name='memberships')
points = models.PositiveIntegerField(default=0, blank=True, null=True)
sub_date = models.DateField(auto_now_add=True)
#other...
If I proceed in this way it is possible to create multiple subscriptions of the user to the same club. How can I solve the problem?

Use unique_together in the model Meta so that a Membership object cannot have the same user and club as another object:
class Membership(models.Model):
...
class Meta:
unique_together = ['user', 'club']
This will return an error if you use a form or the Django admin to create a membership that already exists with that user/club.

Use m2m relationship.
field = models.ManyToManyField(Your_model)

Related

How to Compare ManyToManyField to another ManyToManyField

I have a model of Partner
class Partner(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
group = models.OneToOneField(
Group, on_delete=models.DO_NOTHING, blank=True, null=True)
def __str__(self):
return self.name
I have 2 other models one is CustomUser and other is Quote
class CustomUser(AbstractUser):
#...
name = models.CharField(max_length=160, null=True, blank=True)
partner = models.ManyToManyField(
Partner, blank=True)
class Quote(models.Model):
#...
visibility = models.CharField(max_length=10)
partner = models.ManyToManyField(
Partner, blank=True)
Both have a partner field related with ManyToManyField to Partner Model
Now I want to compare them in the views like:
partner field can have multiple partners like partner1, partner2, partner3
how to to find the partners matching to each other inside the Quote and CustomUser model
Lets say, One of the Quote object have set of [partner1 and partner6] in the ManyToManyField and I only want to have access to that quote to users who also have partner1 and partner6 in their partner ManyToManyField set.
So how can I filter and compare them ?
I also read the docs but didn't able to reproduce the solution. help would be appreciated.
Edit : I can explain it a little , lets say From whole set of partner's in the quote if even one partner is matched to set of partners to the CustomUser then CustomUser should also have access to it.
You can .filter(…) [Django-doc] with:
Quote.objects.filter(partner__customuser=my_user)
This will return a QuerySet of Quotes that have at least one Partner in common with my_user.
The same Quote will be returned that many times as there are Partners in common. You can use .distinct() [Django-doc] to avoid that:
Quote.objects.filter(partner__customuser=my_user).distinct()

Django How to organize models so there is only one owner

I have two models Company and User:
class Company(models.Model):
name = CharField("Name", max_length=60)
owner = OneToOneField(
"Employee", related_name='owner', on_delete=SET_NULL, null=True)
class BaseUser(AbstractBaseUser, PermissionsMixin):
objects = CustomUserManager()
join_date = DateTimeField(default=timezone.now)
name = CharField("Name", max_length=60)
email = EmailField(('Email'), unique=True)
company = ForeignKey(Company, on_delete=models.CASCADE)
I need to have only one User as owner. I made it so two models point to each other which doesn't seem right. Is there a way to fix it and still have only one possible owner? I know standard way would be to add is_owner = Boolean to User but it allows other Users to be owners.
A ForeignKey from the Company to the BaseUser is sufficient:
class Company(models.Model):
name = CharField("Name", max_length=60)
owner = ForeignKey(
'Employee',
related_name='companies'
)
class BaseUser(AbstractBaseUser, PermissionsMixin):
objects = CustomUserManager()
join_date = DateTimeField(default=timezone.now)
name = CharField("Name", max_length=60)
email = EmailField(('Email'), unique=True)
# no company
Here we thus link a Company to one user. Two Companys can have the same owner, and it is possible that the BaseUser has no, one, or more Companys where he is the owner.
You can obtain all the companies for which a BaseUser is the owner with:
myuser.companies.all()
If two companies should always point to two different users, you can make use of the OneToOneField [Django-doc].

Django ORM relations one-to-many

I have a model:
class Product(models.Model):
title = models.CharField(max_length=200)
url = models.URLField()
pub_date = models.DateTimeField()
votes_total = models.IntegerField(default=1)
image = models.ImageField(upload_to='images/')
icon = models.ImageField(upload_to='images/')
body = models.TextField()
hunter = models.ForeignKey(User, on_delete=models.CASCADE)
Now I'd like to add a functionality of upvoters to know on what products user has already voted. I need this to allow users vote on the one product only once.
Again, to clarify - user can vote on several products but only once on each.
So the relation is one product - many users (upvoters).
I tried to add the next field but cannot make a migration even if default field is provided. Also I tried to clear the database but again cannot make it work.
upvoters = models.ForeignKey(User, on_delete=models.CASCADE, related_name='upvoted')
I suppose it works the next way:
Field to determine upvoted products.
To check if user has been upvoted on product, call: User.upvoted.filter(id=product.id).count() == 1
This means that user has already upvoted on this product.
What's wrong? What should I change to make it work?
You will have to use ManyToMany, but you can use a custom through model to restrict the product/vote combinations.
To Product class, add:
voters = models.ManyToManyField(User, through='ProductVote', related_name='product_voters')
Then add the custom through model:
class ProductVote(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Vote, on_delete=models.CASCADE)
class Meta:
unique_together = ['user', 'product']
If you try to add a vote for the same user/product combination, an IntegrityError will be raised.

Relational database - Django Rest Framework

I am trying to build relations with my database tables. Im having a tutorial lesson at the moment with 3 tables. for example (auth_user table, partyEvent table, friends table).
Now a user should be able to create just one partyEvent. Friends can join any number of partyEvent created by the users.
The owner id in the Friends model tells the partyEvent and User 'the friend' belongs to.
I am able to restrict the users to create only one partyEvent. But when i try to register friends to a partyEvent, the owner's id is not sent. Instead the default value in:
owner = models.OneToOneField('auth.User', related_name = 'party', on_delete=models.CASCADE, default='1')
is rather sent. Why is that happening?
models
class PartyEvent(models.Model):
name = models.CharField(max_length=100, blank=False)
location = models.CharField(max_length=100, blank=False)
owner = models.OneToOneField('auth.User', related_name = 'party', on_delete=models.CASCADE, default='1')
class Friends(models.Model):
name = models.CharField(max_length=100, blank=False)
owner = models.ForeignKey('auth.User',related_name = 'friends', on_delete=models.CASCADE, default='1')
serializers
class FriendsSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.id')
class Meta:
model = Friends
fields = ('id','name','owner')
You can set current user by assigning serializers.CurrentUserDefault() as your serializer field default. Here is an example from the doc:
owner = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)

Django Admin: Add foreign keys at same time as model

I am a novice in Django and I'm learning the ropes of the admin interface. I have a model with several foreign keys. These foreign keys then reference other foreign keys. On the admin website after I register the Property model and then try to add it I am given a dropdown box for each foreign key model. However this dropdown box only lists existing foreign keys. (http://i.stack.imgur.com/e5LCu.png)
What would be great is if instead of a dropdown box there were extra fields so I could add the foreign key models as I add the property model. That way I wouldn't have to manually add foreign keys and then go back and add some more, and then go back and finally add the property data.
How can I do this? This feels like a simple enough question but after intense Googling I still can't find the answer, so I apologize in advance.
Example of two of my models:
class Address(models.Model):
state = models.ForeignKey('State')
address1 = models.CharField(max_length=200)
address2 = models.CharField(max_length=200)
city = models.CharField(max_length=200)
postal_code = models.CharField(max_length=200)
class Property(models.Model):
address = models.ForeignKey('Address', blank=True, null=True)
borrower = models.ForeignKey('Person', blank=True, null=True)
company = models.ForeignKey('Company', blank=True, null=True)
contract = models.ForeignKey('Contract', blank=True, null=True)
loan_balance = models.IntegerField()
name = models.CharField(max_length=200)
primary_email = models.CharField(max_length=200)
primary_phone = models.CharField(max_length=200)
property_no = models.IntegerField()
Example of my admin.py:
# Register your models here.
class PropertyAdmin(admin.StackedInline):
model = Property
class PersonAdmin(admin.StackedInline):
model = Person
class CompanyAdmin(admin.StackedInline):
model = Company
class ContractAdmin(admin.StackedInline):
model = Contract
class CompletePropertyAdmin(admin.ModelAdmin):
inlines = [PropertyAdmin, PersonAdmin, CompanyAdmin, ContractAdmin]
admin.site.register(Property)
One solution to the problem can be, to create a custom form with fields from both the models and at the time of saving the values, first create the instance of Address model and then with that instance save your final Property model.

Categories

Resources