暫無描述

models.py 3.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. from django.core.exceptions import ValidationError
  4. from django.utils import timezone
  5. from taggit.managers import TaggableManager
  6. class Profile(models.Model):
  7. user = models.OneToOneField(User, on_delete=models.CASCADE)
  8. bio = models.TextField(blank=True)
  9. interests = models.CharField(max_length=255, blank=True)
  10. industry = models.CharField(max_length=255, blank=True)
  11. is_verified = models.BooleanField(default=False)
  12. tags = TaggableManager(blank=True)
  13. def __str__(self):
  14. return self.user.username
  15. class Opportunity(models.Model):
  16. title = models.CharField(max_length=255)
  17. description = models.TextField()
  18. created_at = models.DateTimeField(auto_now_add=True)
  19. def __str__(self):
  20. return self.title
  21. class IntroductionRequest(models.Model):
  22. from_user = models.ForeignKey(User, related_name='sent_requests', on_delete=models.CASCADE)
  23. to_user = models.ForeignKey(User, related_name='received_requests', on_delete=models.CASCADE)
  24. message = models.TextField()
  25. is_accepted = models.BooleanField(default=False)
  26. created_at = models.DateTimeField(auto_now_add=True)
  27. def __str__(self):
  28. return f'Introduction request from {self.from_user} to {self.to_user}'
  29. class BenefitEvent(models.Model):
  30. """Immutable ledger of user-to-user benefit/help actions.
  31. benefactor: the user who provided value/help.
  32. beneficiary: the user who received value.
  33. points: positive integer weight for the action.
  34. kind: action type (accepted_answer, review_helpful, referral, recommendation).
  35. meta: optional JSON metadata (e.g., related object ids).
  36. """
  37. KIND_ACCEPTED_ANSWER = "accepted_answer"
  38. KIND_REVIEW_HELPFUL = "review_helpful"
  39. KIND_REFERRAL = "referral"
  40. KIND_RECOMMENDATION = "recommendation"
  41. KIND_CHOICES = (
  42. (KIND_ACCEPTED_ANSWER, "Accepted Answer"),
  43. (KIND_REVIEW_HELPFUL, "Review Marked Helpful"),
  44. (KIND_REFERRAL, "Referral"),
  45. (KIND_RECOMMENDATION, "Recommendation"),
  46. )
  47. benefactor = models.ForeignKey(
  48. User, on_delete=models.CASCADE, related_name="benefit_given"
  49. )
  50. beneficiary = models.ForeignKey(
  51. User, on_delete=models.CASCADE, related_name="benefit_received"
  52. )
  53. points = models.IntegerField()
  54. kind = models.CharField(max_length=32, choices=KIND_CHOICES)
  55. meta = models.JSONField(default=dict, blank=True)
  56. # Use default=timezone.now so tests and backfills can set explicit timestamps
  57. created_at = models.DateTimeField(default=timezone.now, db_index=True)
  58. class Meta:
  59. indexes = [
  60. models.Index(fields=["benefactor", "created_at"]),
  61. models.Index(fields=["beneficiary", "created_at"]),
  62. models.Index(fields=["kind", "created_at"]),
  63. ]
  64. ordering = ("-created_at", "-id")
  65. def clean(self):
  66. if self.benefactor_id and self.beneficiary_id and self.benefactor_id == self.beneficiary_id:
  67. raise ValidationError("Self-benefit is not allowed.")
  68. if self.points is None or self.points <= 0:
  69. raise ValidationError("Points must be a positive integer.")
  70. def save(self, *args, **kwargs):
  71. # Ensure validation always runs to enforce integrity
  72. self.full_clean()
  73. return super().save(*args, **kwargs)
  74. def __str__(self):
  75. return f"{self.kind} +{self.points} from {self.benefactor_id} to {self.beneficiary_id}"