Django form: reference fields from foreign key - python

I'm making a task tracker webapp (the full source code is also available) and I have a database structure where each task has a title, a description, and some number of instances, that can each be marked incomplete/incomplete:
class Task(models.Model):
title = OneLineTextField()
description = models.TextField(blank=True)
class TaskInstance(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE)
is_complete = models.BooleanField()
The task and the instances can be shared separately, although access to the instance should imply read access to the task. This is intended for classroom situations, where the teacher creates a task and assigns it to their students.
class TaskPermission(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='permissions')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='task_permissions_granted')
shared_by = models.ForeignKey(User, on_delete=models.PROTECT, null=True, related_name='task_permissions_granting')
can_edit = models.BooleanField(default=False)
class Meta:
unique_together = 'task', 'user', 'shared_by',
class TaskInstancePermission(models.Model):
task_instance = models.ForeignKey(TaskInstance, on_delete=models.CASCADE, related_name='permissions')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='task_instance_permissions_granted')
shared_by = models.ForeignKey(User, on_delete=models.PROTECT, null=True, related_name='task_instance_permissions_granting')
can_edit = models.BooleanField(default=False)
class Meta:
unique_together = 'task_instance', 'user', 'shared_by',
My question is how to create a form for TaskInstances with fields for its is_complete, as well as its Task's title and description. Would something like this work? Or would I need to implement my own save and clean methods?
class TaskForm(ModelForm):
class Meta:
model = TaskInstance
fields = ('is_complete', 'task__title', 'task__description')

I think inlineformset_factory is what I'm looking for!
Actually, it does not seem to be useful: it is for multiple forms of the same type, not different types...

Related

I cant use the objects attribute in django project

I created a Projects model
class Projects(models.Model):
name = models.CharField(max_length=257, unique=True, null=False)
description = models.TextField()
active_issue_count = models.IntegerField(default=0) # functiona bağlanmalı
solved_issue_count = models.IntegerField(default=0) # functiona bağlanmalı
is_active = models.BooleanField()
start_date = models.DateTimeField()
deadline = models.DateTimeField()
and I want to use this project model Projects.objects.all() with this code but when I typed in pyCharm shows me this suggestion
but while I try to use this model
class User(AbstractUser, PermissionsMixin):
objects = UserManager()
related_group = models.CharField
current_project = models.ForeignKey(to='core.Project',
related_name='current_project', on_delete=models.PROTECT, null=True)
total_worked_project = models.IntegerField(default=0) # functiona bağla
active_work_project_count = models.IntegerField(default=0) # functiona bağla
REQUIRED_FIELDS = ['email']
`
I can use User.objects.all() without suggestion what should I do anyone can help me ?
PyCharm just don't follow some object's relation. Here it has no clue that this Model class has related Manager, that you can call with objects.
You can ignore it in PyCharm so it will not bother you.
More actions... => Ignore (...)

how to set object admin moderation in drf

I am using python 3.8 and django 4.0.6 + drf 3.13.1
There are models
class Profile(models.Model):
user='US'
manufacturer = 'MA'
admin='AD'
choice=[
(user, 'User'),
(manufacturer, 'Manufacturer'),
(admin, 'Admin')
]
user_company = models.CharField(max_length=2, choices=choice)
user = models.OneToOneField(User, on_delete=models.CASCADE)
last_request = models.JSONField(null=True)
class ProfileCompany(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.OneToOneField('Company', on_delete=models.CASCADE)
classCompany(models.Model):
id_company = models.IntegerField(null=True, unique=True)
Company = models.CharField(max_length=128)
Direction = models.CharField(max_length=512, blank=True)
Description = models.TextField(null=True, blank=True)
Categories = ArrayField(base_field=models.CharField(max_length=128), null=True, blank=True)
Products = ArrayField(base_field=models.CharField(max_length=128), null=True, blank=True)
Serializer
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model=Company
fields = '__all__'
The task is to make the pre-moderation of the creation and updating of companies by the admin.
Manufacturer creates a new company or updates data in it, this data is not visible to all users, but only to the admin. The admin accepts or rejects this data with a comment (in this case, the Manufacturer receives a message with this comment, corrects the data and sends the data again for moderation)
I could not connect django-moderation, because it is not suitable for REST.
Are there ready-made libraries or solutions?

Django user subscribe user relation

I`m creating a simple blog now, and the main problem is to create a relation between Users. I use a default django User which should subscribe another user who is an author of post.
I have only one Post model in my app
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=128)
content = models.TextField(blank=True)
created_on = models.DateTimeField(auto_now_add=True)
seen = models.ManyToManyField(User, related_name='blog_posts', blank=True)
The relationship you're referring to isn't about the Post model as I understand it. So I think it might be better if you create a separate model. I share a model below as an idea, you can edit field names or add/delete fields according to your needs.
class AuthorSubscription(models.Model):
author = models.OneToOneField(User, on_delete=models.CASCADE, 'author_subscription')
subscribers = models.ManyToManyField(User, related_name='subscriptions', blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

Django - extend the User model with a Profile but also different user kind

I want to extend the user model in Django (2.2) and combine it with a Host and a Guest entities that have also specific fields.
In the official documentation, it is recommended to create a "Profile" class with a OneToOne field that reference the User primary key.
I can see 3 ways of doing it:
Solution 1: Profile, Host and Guest model:
class Profile(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=2)
class Host(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
host_field= models.CharField(max_length=500)
class Guest(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
guest_field = models.BooleanField(null=False)
Solution 2: Host and Guest model (with Profile fields duplicated)
class Host(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=2)
host_field = models.CharField(max_length=500)
class Guest(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=2)
guest_field = models.BooleanField(null=False)
Solution 3: Profile model (containing Guest and Host fields)
class Profile(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=2)
is_host = models.BooleanField(null=False)
guest_field = models.BooleanField(null=False)
host_field = models.CharField(max_length=500)
All those solutions are working.
My question is: "Which one is the smartest, all things considered" (less database access, less code to write, easier to maintain, less limitations, etc..)
After digging further into Django's doc and reading the article mentioned by #sam that explain how to implement multi user types in Django, I found my answer.
It is written in the Django doc that "it’s highly recommended to set up a custom user model, even if the default User model is sufficient for you".
Here is what it gives in my case:
class User(AbstractUser):
is_guest = models.BooleanField(default=False)
is_host = models.BooleanField(default=False)
language = models.CharField(max_length=2)
class Host(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
host_field = models.CharField(max_length=500)
class Guest(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
guest_field = models.BooleanField(null=False)
in settings.py:
AUTH_USER_MODEL = 'path.to.User'
Guest or Host record are inserted when you create a new user:
user = User.objects.create_user(...)
if is_host:
Host.objects.create(user=user)
else:
Guest.objects.create(user=user)
I appreciate the fact that I can detect the user "type" in the request object (with request.user.is_host).
By extending the user class, you can also use the email field for login, and make it unique:
class User(AbstractUser):
[...]
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
If once in production you chose to add fields in the User model, it is possible if you have set up a custom user model.
Otherwise you will be stuck with profiles, so I advise you to follow Django's guidelines and always extending the user class, even if you don't need it (yet).
I would propose a 4:th way, using a mixin with an abstract model. This will derive the fields of the abstract model to the ones that you apply it to. This way you don't need to rewrite code and still apply it to different models:
class ProfileMixin(models.Model):
k_user = models.OneToOneField(User, on_delete=models.CASCADE)
language = models.CharField(max_length=2)
class Meta:
abstract = True
class Host(ProfileMixin):
host_field = models.CharField(max_length=500)
class Guest(ProfileMixin):
guest_field = models.BooleanField(null=False)

Many to Many or One to Many Django

I have the following two models in Django. One is basically an extension of the base Django user class and the other is a company model. I want to say that a user can belong to one or more companies and that a company can also have one or more contacts = "Users". Would this be a correct setup? How should I represent the tie between user and company?
User Profile model:
class Profile(models.Model):
user = models.OneToOneField(User)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
Company model:
class Company(models.Model):
name = models.CharField(max_length=120)
account_name = models.CharField(max_length=10, default="")
sales_rep = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_sales", default="")
csr = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_csr", default="")
class CompanyContact(models.Model):
name = models.CharField(max_length=40, default="")
email = models.CharField(max_length=50, default="")
user = models.ForeignKey(User)
company = models.ForeignKey(Company)
First, is there a reason to extend the User model? The default model already includes a first_name and last_name field, so you don't need an additional model just for that data. Similarly, you don't really need CompanyContact because the User model also contains email and name (again, through first_name and last_name) fields.
You can add in your contacts as a ManyToManyField. If you want to use the custom Profile model instead of User, just replace User (in the ManyToManyField) with Profile.
class Company(models.Model):
name = models.CharField(max_length=120)
account_name = models.CharField(max_length=10, default="")
sales_rep = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_sales", default="")
csr = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_csr", default="")
contacts = models.ManyToManyField(User) # or Profile
This allows each company to have many contacts and each user to be a contact of many companies – thus many-to-many.
Now, if you wanted extra data to describe the many-to-many relationship, you can have another model for that. For example, you may want to keep a record if the contact is still active or what their role is. So, you may have a CompanyContact model that is similar to:
class CompanyContact(models.Model):
active = models.BooleanField(default=False)
role = models.CharField(max_length=50, default="")
user = models.ForeignKey(User) # or Profile
company = models.ForeignKey(Company)
Then, declare the ManyToManyField relationship to use this new model:
class Company(models.Model):
...
contacts = models.ManyToManyField(User, through="CompanyContact")
# or contacts = models.ManyToManyField(Profile, through="CompanyContact")

Categories

Resources