How to get data from ManyToManyField - Django - python

I have a problem with retrieving data from this ManyToManyField (users) of a model Event:
class Event(models.Model):
name = models.CharField(max_length=26)
description = models.CharField(max_length=200)
date = models.DateField()
user = models.ForeignKey(User)
users = models.ManyToManyField(User, related_name="users", blank=True)
image = models.ImageField(
upload_to='images/',
default='images/default.png'
)
users = models.ManyToManyField creates an additional table "events_event_users", It stores user_id and event_id fields. So I want to output all event information from Event model, where user_id from that additional table is equal to request.user. Please help, how should I do this?

You can do request.user.users.all()
Note, this is unnecessarily confusing because of the related_name you've set, which defines the backwards relation from User to Event. Leave that out, and the code is more comprehensible:
request.user.event_set.all()
(If you must set one, at least call it events, not users.)

Related

How do I limit a django model's field choices using one of the previous fields?

The following is in my models.py:
class SensorType(models.Model):
hardware_type = models.CharField(max_length=100)
is_static = models.BooleanField(default=False)
# Some other fields
class Sensor(models.Model):
device_id = models.CharField(max_length=100, primary_key=True)
sensor_type = models.ForeignKey(SensorType, on_delete=models.PROTECT)
# Some other fields
class Asset(models.Model):
name = models.CharField(max_length=100)
sensor_type = models.ForeignKey(SensorType, on_delete=models.PROTECT) # I need to use this field to filter below
sensor = models.ForeignKey(Sensor, on_delete=models.PROTECT, limit_choices_to={'sensor_type': WHAT DO I PUT HERE?},)
# Some other fields
I need to limit the choices in the sensor field of asset so that only sensors with the sensor_type set in the field immediately above, show up.
The reasoning behind this is that there will eventually be many sensors and it would be very useful to filter this. Initially I only need this to work from the admin page but this will eventually extend when I make my Create and Update Views.
Is this even possible? I'm essentially trying to access attributes before the object has actually been created.
After reading several other questions such as this one I have also looked into ModelChoiceField but the same issue exists of trying to access the form data before it has been submitted.
I'm very open to changing the model structure if that is what is required.

Is there any way to select a value dynamically for a model's related field in runtime?

I want to achieve a functionality, where I need to select a django model (e.g from a drop down list), and after selecting one, all the objects of that model shows up.
class Thread(models.Model):
sender = models.(???) # This need to be a field that can store a different model on a run time.
receiver = models.(???) # same here.
Is there any way that I can dynamically first select the model and then pick an object of that list. I have seen this functionality in odoo. But is there anything in Django?
Use Inheritance for in your Model and map your foreign key to User, and then pass either a teacher of student object.
You can use the many-to-many filed with multiple available choices of "Student" and "Teacher" from another Model.
class UserRole(models.Model):
STUDENT = 'STUDENT'
TEACHER = 'TEACHER'
ROLE_CHOICES = (
(STUDENT, 'student'),
(TEACHER, 'teacher'),
)
role_name = models.CharField(max_length=255, choices=ROLE_CHOICES)
def __str__(self):
return "{}".format(self.role_name)
class User(AbstractUser):
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(_('email address'))
role = models.ManyToManyField(UserRole)
Class Thread(models.Model):
sender = models.OneToOneField(User, on_delete=models.CASCADE)
receiver = models.OneToOneField(User, on_delete=models.CASCADE)
This way you can only put available roles in sender and receiver fields of Thread.
The solution was possible with ajax too, but there also is another way in django which I was searching for.
class Test(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
Have a good one.

django user defined fields and answer model

Similar to this: User defined fields model in django
I am creating a COVID Prescreening system for a school project. Event creators will be able to create forms, which consist of basic questions such as temperature, contact with covid in the last 14 days, etc. as well as provide custom questions for the attendee to answer which I cannot predict.
For example, the event creator could ask 2 questions:
How are you feeling today?
Have you been to a party in the last week?
And every attendee for that event would have to fill out these 2 questions in addition to the standard questions.
The model for this is:
class Event(models.Model):
''' model for an event '''
creator = models.ForeignKey("Account", on_delete=models.CASCADE)
title = models.CharField(max_length=200, help_text="Enter a title for this event")
start_time = models.DateTimeField()
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
custom_questions = models.ManyToManyField(CustomQuestion)
def __str__(self):
return f'{self.title} {self.uuid}'
Each custom question is essentially a key/value model:
class CustomQuestion(models.Model):
question = models.CharField(max_length=200)
response = models.CharField(max_length=200, blank=True)
The user will fill out the COVID Form, which will create an object as such:
class CovidScreenData(models.Model):
custom_responses = models.ManyToManyField(CustomQuestion)
temperature = models.DecimalField(max_digits=5, decimal_places=2, default=98.6)
contact_with_covid = models.BooleanField(default=False)
This data is embedded in the larger response, which ties everything together
class Response(models.Model):
''' model for a completed covid screen '''
account = models.ForeignKey('Account', on_delete=models.SET_NULL, null=True)
time = models.DateTimeField()
event = models.ForeignKey('Event', on_delete=models.CASCADE)
details = models.ForeignKey('CovidScreenData', on_delete=models.CASCADE)
def __str__(self):
return f'{self.account.user.username}\'s Response ({self.event.title})'
When the attendee is filling out the form, I want them to be given the custom_questions for the event they are filling out.
My idea is that when they are presented with the form, each question in custom_questions will be looped through and displayed. When the user submits, their response, as well as the original question, are saved in the custom_responses variable.
What is the correct organization to do this? I am asking this rather than how do I display the questions to the user and save their responses in the model.
If you want to save the response correspond to the question I think you can not use ManytoMany field on this part
class Event(models.Model):
...
custom_questions = models.ManyToManyField(CustomQuestion)
...
you should use ManytoOne for Event relationship with CustomQuestion (adding foreign key to Event on CustomQuestion). It's because you store the answer on the same row with the question so other event should not use the same row of CustomQuestion(containing question and answer).
also you can't store a ManytoMany in the CovidScreenData about the custom_response that actually contains CustomQuestion because the reason on my first explanation.
If you want to get and store the answer just go through the Response item, then get the Event item, and then get pairs of question-answer using foreign key on CustomQuestion join with the Event item.

How to insert data into a relational one to one table in django?

I have a UserProfile table which is in relation with the default Django User table. Here's how it looks.
class UserProfile(models.Model):
user = user.OneToOneField(User, on_delete=models.CASCADE)
section = models.CharField(max_length=255, blank=True)
year = models.IntegerField(null=True, blank=True)
course = models.CharField(max_length=255, blank=True)
qrcode = models.CharField(max_length=255, blank=True)
present = models.BooleanField(default=False)
I am trying to insert the data into the UserProfile table using the Django Shell.
from users.models import UserProfile
a = UserProfile(qrcode="hello")
a.save()
This is how I have always known to insert data into tables, it has always worked. BUT when i try to do this in UserProfile model. I get this exception. NOT NULL constraint failed: users_userprofile.user_id. Which in turn is caused by the following exception Error in formatting: RelatedObjectDoesNotExist: UserProfile has no user.
I somewhat understand that I somehow need to supply a user instance. But I am clueless as to how. Can someone please help me.
Firstly you need to create User.
u1 = User(username='user1')
u1.save()
Create a UserProfile. Pass the ID of the “parent” object as this object’s ID:
v1 = UserProfile(user=u1, ....)
v1.save()
refer this
You need to create your User first
user = User.objects.create(username='user')
and then you can do:
user_profile = UserProfile.objects.create(user=user, ...)

Django ManyToMany Relationship can't access fields

I have a list model that uses User as foreign key twice.
The 1st is as ForeignKey to the creator. And 2nd as ManyToManyField for users for that list
class TodoList(models.Model):
creator = models.ForeignKey(User, default=1,related_name='created_by')
list_users = models.ManyToManyField(User,related_name='list_users')
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=10, blank=True, null=True)
status = models.SlugField(choices=STATUS_CHOICES, default='active', max_length=10)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
What I want to do is:
Get the users for the list.
Get the list for the logged in user.
Here is my code for #1:
todolist = get_object_or_404(TodoList, slug=list_slug)
users = todolist.list_users
The first line works fine. But when I get the list_users it will return auth.User.None even though the list has 3 users added to it through admin.
Here is my code for #2:
user = request.user
user_todo_lists = user.todolist.all()
The page will send an:
AttributeError: 'User' object has no attribute 'todolist'
but when I rename the list_users to user. It will work just fine. What could be the problem?
Regarding your first problem, you probably want todolist.list_users.all(). (That is, you want a QuerySet, not a Manager.)
Regarding your second problem, I'm not sure which relation you're actually trying to get at, but in either case you need to use the attribute defined by related_name. (That is, user.created_by.all() or user.list_users.all().)

Categories