7👍
Ultimately I settled on:
from django.db import models, transaction
class Course(models.Model):
student_group = models.OneToOneField(Group, related_name="course_taken")
@transaction.commit_on_success
def save(self, *args, **kwargs):
if not self.student_group_id:
self.student_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_student')
super(Course, self).save(*args, **kwargs)
Edit (2014/12/01): @Shasanoglu is correct, the above code does not really work due to id not existing yet. You have to do related object creation after you call save (so you call super.save, create the related object, update this object and call super.save again — not ideal. That or you omit the id from the Group name and it’s fine). Ultimately though, I moved the automated-related-object creation out of the model entirely. I did it all in the save method of a custom form which was much cleaner, and gave up on using this model in the admin interface (which was why I insisted on doing all of this in the model method in the first place)
14👍
You can use the models.signals.post_save signal to handle such case:
from django.db import models
class Course(models.Model):
student_group = models.OneToOneField(Group, related_name="course_taken")
teacher_group = models.OneToOneField(Group, related_name="course_taught")
def create_course_groups(instance, created, raw, **kwargs):
# Ignore fixtures and saves for existing courses.
if not created or raw:
return
if not instance.student_group_id:
group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_student')
instance.student_group = group
if not instance.teacher_group_id:
teacher_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_teacher')
instance.teacher_group = teacher_group
instance.save()
models.signals.post_save.connect(create_course_groups, sender=Course, dispatch_uid='create_course_groups')
- Django reverse error: NoReverseMatch
- Remove non-ASCII characters from a string using python / django
- Django, Apache2 on Google Kubernetes Engine writing Opencensus Traces to Stackdriver Trace
- Passing a user, request to forms
- Pycharm remote project with virtualenv
1👍
I used wjin’s solution in a similar problem in Django 1.7. I just had to make 2 changes:
- Had to change
commit_on_success
withatomic
self.id
didn’t work because the code runs before the id is set when creating new object. I had to use something else as Group name.
Here is what I ended up doing:
from django.db import models
from django.contrib.auth.models import Group
class Audit(models.Model):
@transaction.atomic
def save(self, *args, **kwargs):
if not hasattr(self,"reAssessmentTeam"):
self.reAssessmentTeam, _ = Group.objects.get_or_create(name='_audit_{}_{}'.format(self.project.id,self.name))
super(Audit, self).save(*args, **kwargs)
project = models.ForeignKey(Project, related_name = 'audits')
name = models.CharField(max_length=100)
reAssessmentTeam = models.OneToOneField(Group)
I know that this might cause problems if the name is too long or someone somehow manages to use the same name but I will take care of those later.
- Django's get_current_language always returns "en"
- How do I convert kilometres to degrees in Geodjango/GEOS?
- Django QuerySet Custom Ordering by ID
1👍
Check out my project for this at https://chris-lamb.co.uk/projects/django-auto-one-to-one which can automatically create child model instances when a parent class is created.
For example, given the following model definition:
from django.db import models
from django_auto_one_to_one import AutoOneToOneModel
class Parent(models.Model):
field_a = models.IntegerField(default=1)
class Child(AutoOneToOneModel(Parent)):
field_b = models.IntegerField(default=2)
… creating a Parent
instance automatically creates a related
Child
instance:
>>> p = Parent.objects.create()
>>> p.child
<Child: parent=assd>
>>> p.child.field_b
2
A PerUserData
helper is provided for the common case of creating instances when a User
instance is created.
- Django: default language i18n
- Django: "order" a queryset based on a boolean field
- VS Code: Python Interpreter can't find my venv