I have problem with 1 query connected with ManyToManyField. We have 2 related models: User and Event. Model Event has 2 relations with User, it must have 1 organizer and any number or participants - organizer cannot be participant (I skipped the code which is responsible for validation of that). Now, as an example, what I want is all participants from events I organized. Problem is that below query only gets request.user himself, skipping all participants alltogether. Is there a way to achieve what I need without any custom query? thanks
#models.py
class User(models.Model):
name = models.CharField(max_length=100)
class Event(models.Model):
name = models.CharField(max_length=100)
organiser = models.ForeignKey(User)
participants = models.ManyToManyField(User, related_name='participants', blank=True, null=True)
#views.py
def assess_partners(request):
users = User.objects.filter(event__organizer=request.user)
return render(request, 'some template.html', {'users': users})
Things will be clearer if you use better related_names, e.g.:
class Event(models.Model):
name = models.CharField(max_length=100)
organiser = models.ForeignKey(User, related_name='events_as_organiser')
participants = models.ManyToManyField(User, related_name='events_as_participant', blank=True)
what I want is all participants from events I organized
User.objects.filter(events_as_participant__organiser=request.user).distinct()
Related
I have a page that displays a list of interviewers and some important info about each user.
One of the things that I want it to show is the number of users who have been interviewed by that specific interviewer.
I wrote a view like this:
class ManagerUsers(ListView):
model = User
template_name = 'reg/manager-users.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['scientific_interviewers'] = User.objects.filter(role='theory_interviewer').all()
context['interviewed_number'] = len(ScientificInfo.objects.filter(user__role='applicant', is_approved=True, interviewer=?????))
the interviewer field should be equal to that object's user but I don't know what to do exactly.
the output should be something like this:
object 1 : user's name, user's other info, user's interviewed_number
....
these are my models:
USER_ROLE_CHOICES = (('0', 'applicant'),
('1', 'theory_interviewer'),)
class User(AbstractUser):
id = models.AutoField(primary_key=True)
role = models.CharField(max_length=25, null=True, choices=USER_ROLE_CHOICES, default=USER_ROLE_CHOICES[0][0])
username = models.CharField(unique=True, max_length=13)
first_name = models.CharField(max_length=32, null=True, default=None)
last_name = models.CharField(max_length=64, null=True, default=None)
class ScientificInfo(models.Model):
id = models.AutoField(primary_key=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user')
interviewer = models.OneToOneField(User, on_delete=models.CASCADE, related_name='interviewer')
is_approved = boolean field
You can override the .get_queryset() method [Django-doc] to return only the interviewers. By using .annotate(…) [Django-doc] you can add an extra attribute to these Users:
from django.db.models import Count
class ManagerUsersView(ListView):
model = User
context_object_name = 'scientific_interviewers'
template_name = 'reg/manager-users.html'
def get_queryset(self):
return super().get_querset().filter(
role='1'
).annotate(
interviewed_number=Count('interviewer', filter=Q(interviewer__user__role='0', interviewer__is_approved=True))
)
The Users that arise from this queryset will have an extra attribute .interviewed_number with the number of approved ScientificInfos where that user was the interviewer.
Note: In Django, class-based views (CBV) often have a …View suffix, to avoid a clash with the model names.
Therefore you might consider renaming the view class to ManagerUsersView, instead of ManagerUsers.
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the User model to the ScientificInfo
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the interviewer relation to interviews.
What is the process that you follow to create model in Django? Thanks.
The most important part of a model – and the only required part of a model – is the list of database fields it defines. Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like clean, save, or delete.
Models.py
from django.db import models
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
You can start here Documentation
See also Django Girls Models
Basically, I have two models: User and Event. An event is always associated with one user.
class User(models.Model):
user_id = models.AutoField(primary_key=True)
username = models.CharField(max_length=255, unique=True)
hashed_password = models.CharField(max_length=255)
class Event(models.Model):
event_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=255)
description = models.TextField(max_length=255, blank=True, default='')
user = models.ForeignKey(User)
And then I have the following form for Event.
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['title', 'description', 'user']
I can succesfully show this form in my template to create an event. I can also associate a user to a form successfully with Select field when the users number are still few.
Now the problem is, when I have 1M users in database, my browser crashes when loading the template. Any idea how to solve this one? I was thinking about using AJAX and then search user that matches the username, but I'd like to hear other better approaches. Thanks!
I'm working on a Django project generated via Mezzanine. I've been able to create my models, however I want to have a form where an admin can select from a list to assign a value in a many to many or a one to many relationship. For example, I have a model for Schemas:
class Schema(AutoCreatedUpdatedMixin, SoftDeleteMixin):
"""List of all Schemas in a given database"""
name = models.CharField(max_length=128, null=False)
status = models.BooleanField(max_length=128, null=False, default=True, verbose_name="Is Active")
description = models.CharField(max_length=65535, null=True, blank=True, default=None)
database = models.ForeignKey(Database, on_delete=models.CASCADE)
pull_requests = models.ManyToManyField(Link)
questions = models.ManyToManyField(Question, blank=True)
comments = models.ManyToManyField(Comment, blank=True)
technical_owners = models.ManyToManyField(Employee, related_name='technical_owners_schemas', blank=True)
business_owners = models.ManyToManyField(Employee, related_name='business_owners_schemas', blank=True)
watchers = models.ManyToManyField(Employee, related_name='watchers_schemas', blank=True)
def __unicode__(self):
return "{}".format(self.name)
And I have a model for Employees
class Employee(AutoCreatedUpdatedMixin, SoftDeleteMixin):
"""List of people with any involvement in tables or fields: business or technical owners, developers, etc"""
name = models.CharField(max_length=256, blank=False, null=False, default=None, unique=True)
email = models.EmailField(blank=True, null=True, unique=True)
def __unicode__(self):
return "{}".format(self.employee)
An employee can own multiple schemas and a schema can be owned by multiple employees. My database has an active employee in it, however when I try to create a Schema the employee shows up as Employee Object. Rather I would want the form to show the Employee.name. How can I do this? My admin file contains the following:
class SchemasAdmin(admin.ModelAdmin):
list_display = ['name', 'status', 'database', 'description']
ordering = ['status', 'database', 'name']
actions = []
exclude = ('created_at', 'updated_at', 'deleted_at')
First of all are you using python 2 or 3? For 3, the __str__ method should be used instead of __unicode__. I am writing this because it seems that there's a problem with the __unicode__ method of Employee, which although is defined as:
def __unicode__(self):
return "{}".format(self.employee)
th Employee class does not have an employee attribute (unless there's such an attribute in the mixins that class inherits from (AutoCreatedUpdatedMixin, SoftDeleteMixin) but I don't think that is the case.
In any case, the problem is that you haven't defined a propery __str__ (if using python 3) or __unicode__ (for python 2) method on the Employee class - just define it like:
return self.name
and you should see the employee's name in the django admin select fields.
I'm kind of new to django. While writing the models for an app I'm doing, I felt like I was doing something wrong because of all the foreign keys I was using for a single model (ticket model to be specific)
My thinking at the beginning was that I wanted each Ticket to keep the information on it's creator, what team this ticket is assigned to and the comments made on the ticket. And other information that don't need foreign keys. Am I doing this right ? I dont know why, but I feel like there is a better way.
class Team(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=2000)
members = models.ManyToManyField(User, through='Team_members')
def __str__(self):
return self.name
class Ticket(models.Model):
name = models.CharField(max_length=200)
creator = models.ForeignKey(User, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
comments = models.ForeignKey(Comment, on_delete=models.CASCADE)
#worker = models.ForeignKey(User, on_delete=models.CASCADE) *to be finished
description = models.CharField(max_length=500)
status = models.BooleanField(default=False)
date_opened = models.DateTimeField('date opened')
date_closed = models.DateTimeField('date closed',null=True, blank=True)
def __str__(self):
return self.name
class Team_member:
team = models.ForeignKey(Team)
user = models.ForeignKey(User)
date = models.DateTimeField('date joined')
class Comment:
text = models.CharField(max_length=2000)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.text
Your question actually has very little (like, nothing?) to do with Django.
Please read about database normalization, it should answer your questions.
Regarding your models, I could notice the following:
Your models look quite good. Don't be afraid of foreign keys, they are the main reason you use a relational database :)
I assume, User might be a member of a Team (service?) or somebody who opens a ticket. If so: when you will have worker foreign key, you most likely won't need team in the Ticket model. It will be redundant, as worker would have a relation to Team.
Nitpicking: Team_member is not pythonic, a PEP8 compliant version would be TeamMember