Django - 我可以在另一个模型中使用抽象模型吗?

时间:2016-04-12 05:31:42

标签: django

我是Django的新手(自从我使用数据库以来已经过了几年),可能会围绕一些简单的东西跳舞,我不知道该怎么去谷歌。

基本上,我希望有一个"事件"它可以包含各种类型的数据。假设一个事件是"警报"另一个是"消息。" "闹钟"类型需要不同的字段而不是"消息"因此,将数据存储在一个包含任何事件可能需要的任何类型数据的大表中似乎是有意义的。但是,我希望能够获得给定" event_block"的所有事件的列表。外键。

我已经完成了一些关于抽象模型和代理等的阅读,但我还没有弄清楚一个模型如何引用一个抽象模型(如果这实际上是要采取的路径)。 / p>

models.py:

class Event(models.Model):
  #id auto-generated primary_key
  event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
  event_data = BaseEvent  # This is wrong, but what is right?

class BaseEvent(Models.model):
  class Meta:
    abstract=True
  ... common event info ...

class AlarmEvent(BaseEvent):
  ... event info for alarms ...

class MessageEvent(BaseEvent):
  ... event info for messages ...

理想情况下,我可以在我的模板中创建一个包含所有可用event_types的下拉框,然后单击"提交"按下表单以在我的Event模型中创建该事件(及其必要的事件数据字段),并让Django处理数据库表中处理方式的详细信息。

我错过了什么?

2 个答案:

答案 0 :(得分:1)

首先,这适用于Event模型

class Event(models.Model):
  event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
  event_data = models.ForeignKey(BaseEvent)

但是BaseEventabstract=True AlarmEvent实际上并不存在,但其子MessageEventBaseEvent确实存在。因此,我不确定您是否可以将ForeignKey指向CATEGORY = ( ('field1', 'field name 1'), ('field2', 'field name 2'), ) class Event(models.Model): category = models.CharField(max_length=10, choices=CATEGORY) # SOME OTHER FIELDS... This post about generic foreign key可能有帮助。

其次是关于模型的结构。 IMO,没有抽象的母班,事情可以更简单。带有类别字段的模型怎么样?

public class AlarmReceiver extends BroadcastReceiver
{

    String h_id, habit, habit_desc, habit_time;
    //public static Ringtone ringtone;

    @Override
    public void onReceive(Context mContext, Intent arg1) 
    {
        String selectedRitual = arg1.getExtras().getString(AppsConstant.SELECTED_RITUAL);
        String userName = arg1.getExtras().getString(AppsConstant.user_name);

        // Enable {@code SampleBootReceiver} to automatically restart the alarm when the
        // device is rebooted.
        ComponentName receiver = new ComponentName(mContext, SampleBootReceiver.class);
        PackageManager pm = mContext.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP); 

        //get data from database        
        GetData getData = new GetData();
        UserRitualModel userReminderSetting  = getData.getRitualsDetails(userName, selectedRitual);
        int isfullScreen = userReminderSetting.getNotificationStyle();
        int ringInSilent = userReminderSetting.getRingInSilent();

        if(ringInSilent ==TableAttributes.ON)
        {
            final AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
            int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);

            audioManager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume,AudioManager.FLAG_ALLOW_RINGER_MODES); 
        }


        Intent i;
        if(isfullScreen==TableAttributes.ON)
        {
              i = new Intent(mContext, ReminderFullScreen.class);
        }
        else
        {
            i = new Intent(mContext, Reminder.class);  
        }
       // i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.putExtra(AppsConstant.SELECTED_RITUAL, selectedRitual);
        i.putExtra(AppsConstant.user_name, userName);

        mContext.getApplicationContext().startActivity(i);

    }
}

默认情况下,您可以通过django admin查看模型的形式。

答案 1 :(得分:1)

这些单独表格的原因是什么?你打算直接查询它们吗?这些事件是否应该共享数据?

如果这些问题的答案是"我不确定" (或者甚至更好"没有")然后如何(而不是创建单独的表)直接保留Event模型上的所有数据?像

这样的东西
class Event(models.Model):
    #id auto-generated primary_key
    event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
    event_data = models.TextField()

并以序列化格式(例如JSON)将数据保存在event_data字段中。或者你可以使用一些插件,例如JSONField的{​​{3}}。

可以分隔一些常见字段,例如:

class Event(models.Model):
    #id auto-generated primary_key
    event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
    event_type = models.CharField(max_length=2)
    event_data = models.TextField()