Django中创建Event实例时传递城市值至Occurrence模型问题咨询
Hey there! Let's tackle this problem step by step. You want to automatically generate an Occurrence instance whenever an Event is created via the Django admin, and make sure the Event's city value gets passed over to the corresponding Occurrence. Here are a few reliable approaches you can use:
Approach 1: Override the Event Model's save() Method
This is a straightforward way to tie the creation logic directly to the Event model itself. Whenever a new Event is saved (i.e., it's a new instance, not an update), we'll create the associated Occurrence and copy the city value.
First, let's assume your models look something like this (adjust fields as needed):
from django.db import models class Event(models.Model): title = models.CharField(max_length=255) city = models.CharField(max_length=100) # Other Event fields... class Occurrence(models.Model): event = models.ForeignKey(Event, on_delete=models.CASCADE) city = models.CharField(max_length=100) # Other Occurrence fields...
Now modify the Event model's save() method:
class Event(models.Model): title = models.CharField(max_length=255) city = models.CharField(max_length=100) # Other Event fields... def save(self, *args, **kwargs): # Check if this is a new instance (not an existing one being updated) is_new = self.pk is None super().save(*args, **kwargs) # Save the Event first if is_new: # Create the Occurrence with the Event's city Occurrence.objects.create( event=self, city=self.city # Add other default values for Occurrence if needed )
Approach 2: Use Django's post_save Signal
Signals are great for decoupling logic—this way, the Occurrence creation doesn't live inside the Event model itself.
Add this to your app's models.py (or a separate signals.py file, just make sure it's imported):
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=Event) def create_occurrence_on_event_save(sender, instance, created, **kwargs): if created: Occurrence.objects.create( event=instance, city=instance.city # Add other default values here )
If you use a separate signals.py, don't forget to import it in your app's apps.py to ensure the signal is registered:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): import your_app_name.signals
Approach 3: Override the Admin's save_model Method
If you only need this behavior when creating Events via the Django admin (and not when creating Events programmatically elsewhere), this is a clean option.
Modify your app's admin.py:
from django.contrib import admin from .models import Event, Occurrence class EventAdmin(admin.ModelAdmin): list_display = ('title', 'city') # Customize as needed def save_model(self, request, obj, form, change): # Save the Event first super().save_model(request, obj, form, change) # Only create Occurrence if it's a new Event (not an update) if not change: Occurrence.objects.create( event=obj, city=obj.city # Add other default values here ) admin.site.register(Event, EventAdmin) admin.site.register(Occurrence)
Quick Notes:
- Make sure the
cityfield onOccurrencematches the type ofEvent'scityfield (e.g., bothCharField, or both foreign keys to aCitymodel). - If you ever need to handle updates to the Event's
citylater (and sync it to Occurrence), you can extend these methods to update the existing Occurrence instead of just creating a new one.
内容的提问来源于stack exchange,提问作者fmakawa

