How to make two Django models with cross relationship? - python

I need two Django models: first with Users, second with Projects.
Between them I need many-to-many relationship with an additional field(s).
How to make the below code working?
from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
projects = models.ManyToManyField(Project, through='UserProjects')
def __str__(self):
return self.name
class Project(models.Model):
name = models.CharField('Name', max_length=50)
users = models.ManyToManyField(User, through='UserProjects')
def __str__(self):
return self.name
class UserProjects(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
is_active = models.BooleanField('Active')
At the end User.projects should return Projects for specified User
and in the same way Project.users should return Users for specified Project.

There's no need to put the m2m field on both sides
Jussi pick one, and Django will automatically create a reverse relationship for the other direction.

from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
def __str__(self):
return self.name
class Project(models.Model):
name = models.CharField('Name', max_length=50)
users = models.ManyToManyField(User, through='UserProjects', related_name='projects')
def __str__(self):
return self.name
class UserProjects(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
is_active = models.BooleanField('Active')

Here is the simplest solution in my opinion:
from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
class Project(models.Model):
name = models.CharField('Name', max_length=50)
class UserProjects(models.Model):
user = models.ForeignKey(User, related_name='projects')
project = models.ForeignKey(Project, related_name='users')
is_active = models.BooleanField('Active')
In above User.projects returns Projects for specified User and also Project.users returns Users for specified Project.

Related

Django admin reverse foregin key relationship

I have a number of different models connected to the User model through a foregin key relationship. I would now like to display all the attributes from the objects connected to the User model in the main admin overview.
models.py
class User(AbstractBaseUser):
username = models.CharField(max_length=60)
lastname = models.CharField(max_length=60, blank=True)
class UserProfile(models.Model):
user_id = models.OneToOneField(
User,
on_delete=models.CASCADE,
primary_key=True,
)
address = models.CharField(max_length=60, blank=True)
admin.py
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('user_firstname', 'user_lastname', 'address')
def user_firstname(self, instance):
return instance.user_id.username
def user_lastname(self, instance):
return instance.user_id.lastname
admin.site.register(UserProfile, UserProfileAdmin)
The code above works perfectly well to display attributes from "User" in "Userprofile", but how do I do this the other way around? In my code I currently have 4 different objects connected to the User object so keen to find a way to display all the data there.
use inlines
models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
admin.py
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
more info read https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#inlinemodeladmin-objects

Roles in django model

I have a model in django, in which there will be several roles - regular user, admin and manager. Each of them will be able to do something else. Is the following model OK to work correctly?
class Team(models.Model):
name = models.CharField('Name', max_length=128)
users = models.ManyToManyField(User)
admins = models.ManyToManyField(User)
managers = models.ManyToManyField(User)
def __str__(self):
return self.name
This might work. If the number of roles is large, or dynamic (as in roles can be added, removed, renamed, updated). You could introduce a ternary relation, like:
from django.conf import settings
class Role(models.Model):
name = models.CharField(max_length=128)
class Team(models.Model):
name = models.CharField('Name', max_length=128)
members = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
role = models.ForeignKey(Role, on_delete=models.PROTECT)

relationships in django 2 models.py

I want to define a relationship between Book and Member through Borrow in models.py
ER
But I don't know how to define the Borrow relationship.
In the Borrow table it must be determined which books have been borrowed by who and which books have been returned on which date. Should I use another table for this date field?
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext as _
class CategoryType(models.Model):
category_name = models.CharField(max_length=200)
def __str__(self):
return self.category_name
class Book(models.Model):
name = models.CharField(verbose_name="عنوان", max_length=128)
number_of_copy = models.IntegerField(default=0)
writer = models.CharField(max_length=64)
B_category = models.ForeignKey(CategoryType, on_delete=models.CASCADE)
class Meta:
ordering = ["B_category"]
def __str__(self):
return self.name
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(member, on_delete=models.CASCADE)
books = models.ManyToManyField(Book)
def __str__(self):
return self.id
class Member(AbstractUser):
pass
I think in the Member class I should have a field containing borrow_id, but how?
It seems to me that you need to use a ManyToMany relationship with a through model (this way you can store extra information for every row of the Borrow model)
...
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(Member, on_delete=models.CASCADE)
book = models.ForeignKey(Book)
def __str__(self):
return self.id
...
class Member(AbstractUser):
borrowed_books = models.ManyToManyField(Book, through='Borrow')
Maybe this link (https://docs.djangoproject.com/es/2.1/ref/models/fields/#django.db.models.ManyToManyField.through) could clarify it more.

Django ModelForm ForeignKey query

I want to have a form which only offers the user to post a question for a project he is participating in.
models.py:
class Project(models.Model):
project_name = models.CharField(max_length=255, unique=True, blank=False)
def __str__(self):
return str(self.project_name)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
project = models.ManyToManyField(Project)
def __str__(self):
return str(self.user)
class Question(models.Model):
title = models.CharField(max_length=255, blank=False)
content = tinymce_models.HTMLField(blank=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
...
def __str__(self):
return str(self.title)
class QuestionForm(ModelForm):
class Meta:
model = Question
fields = ['title', 'content', 'project']
in views.py:
form = QuestionForm()
form.fields["project"].queryset = Project.objects.filter(project_name__in=request.user.profile.project.all())
But somehow the result of the query always stays empty.
Does somebody maybe have an idea what I am missing?
Your query is over complicated. You should just use the user's projects directly:
form.fields["project"].queryset = request.user.profile.project.all())

Django Many-to-Many Relation or One-to-Many relation

i have this tables in my django :
class User(models.Model):
username = models.CharField(max_length=40)
class Photo(models.Model):
publish_by = models.ForeignKey(User)
name = models.CharField(max_length=40)
desc = models.CharField(max_length=40)
User could publish Phtotos , and they can like Photos .but i don't know how to write the like in the phtoto , should i use one to many or many to many ?
and how could i get the Users that like a Photo .
thanks for help .
UPDATE
In the end I decided to use a many to many with a through model because I also wanted to record the time. The models I have settled on are these
class User(models.Model):
username = models.CharField(max_length=40)
class Photo(Model):
author = models.ForeignKey(User, related_name='%(class)ss')
publish_time = models.DateTimeField(default=datetime.datetime.now)
liked_by = models.ManyToManyField(User, related_name="likes",through='PhotoLike',)
def like(self, user):
liked, created = PhotoLike.objects.get_or_create(photo=self,user=user)
return liked
def save(self, *args, **kwargs):
super(Photo, self).save(*args, **kwargs)
class Meta:
app_label = 'meinv'
class PhotoLike(models.Model):
user = models.ForeignKey(User)
photo = models.ForeignKey(Photo)
like_time = models.DateTimeField(default=datetime.datetime.now)
class Meta:
app_label = 'meinv'
You just need to think about how photos are liked.
Can a user like many photos?
Can many photos be liked by the one user?
Then it is a many to many.
You would implement it like this
class Photo(models.Model):
publish_by = models.ForeignKey(User)
name = models.CharField(max_length=40)
desc = models.CharField(max_length=40)
liked_by = models.ManyToManyField(User, related_name="likes")
Then, it works like this, you can add likes to a photo by
photoInstance.liked_by.add(user)
Access the likes of a photo this way
photoInstance.liked_by.all()
To get all the photos a user liked
user.likes.all()
class Like(models.Model):
user = models.ForeignKey(User)
photo = models.ForeignKey(Photo)

Categories