使用模块添加自定义字段时出错:ParseError:" arch"在解析文件

时间:2016-07-20 10:22:55

标签: openerp odoo-9

我正在尝试使用模块向Odoo 9 res.partner模型添加自定义字段。我使用scoffold命令生成模块文件,并将以下代码添加到models.py和views.xml。

模型/ models.py

from openerp import models, fields, api
class SeicoPartner(models.Model):
    _name  = 'res.partner'
    _inherit  = 'res.partner'

   no_of_ac = fields.Integer('No of AC', default=0)
   review = fields.Char('Company Review')

视图/ views.xml

<openerp>
<data>
    <record id="res_partner_field_ac" model="ir.ui.view">
        <field name="no_of_ac">10</field>
    </record>
</data>
</openerp>

从Apps屏幕安装此模块后,出现以下错误:

Traceback (most recent call last):
  ...
  File "C:\Program Files (x86)\Odoo 9.0-20160719\server\openerp\addons\base\ir\ir_ui_view.py", line 344, in create
ParseError: "arch" while parsing file:///C:/Program%20Files%20(x86)/Odoo%209.0-20160719/server/openerp/addons/mymodule1/views/views.xml:4, near
<record id="res_partner_field_ac" model="ir.ui.view">
            <field name="no_of_ac">10</field>

        </record>

Settings -> Database Structure -> Fields我可以看到res.partner有no_of_ac字段,但在编辑任何客户详细信息时该字段不可见。

3 个答案:

答案 0 :(得分:1)

那是因为你错过了描述视图类型(xml或html)的arch字段,在大多数情况下xml很好,

您还缺少模型名称,视图名称,因此odoo不知道您的视图属于哪个模型。您还必须指定要覆盖的现有模型表单以及您希望新字段所在的位置,在这种情况下,我使用xpath表达式在父视图中的网站字段后显示字段,它可以在任何你想要的地方。

<openerp>
<data>
    <record id="res_partner_field_ac" model="ir.ui.view">
      <field name="name">res.partner.form</field>
      <field name="model">res.partner</field>
      <field name="inherit_id" ref="base.view_partner_form"/>
      <field name="arch" type="xml">
        <xpath expr="//field[@name='website']" position="after">
          <field name="no_of_ac" />
        </xpath>
      </field>
    </record>
</data>
</openerp>

如果您只想扩展模型并为其添加额外字段,也不需要指定_name,因此请将模型代码更改为

from openerp import models, fields, api
class SeicoPartner(models.Model):
    _inherit  = 'res.partner'

   no_of_ac = fields.Integer('No of AC', default=0)
   review = fields.Char('Company Review')

答案 1 :(得分:1)

您正在public class NotificationReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //Log.d("NotificationReceiver", "onReceive"); this.sendNotif(context); //trying to see if there is already an alarm in place (for reboot) boolean alarmUp = (PendingIntent.getBroadcast(context, 100, new Intent(), PendingIntent.FLAG_NO_CREATE) != null); Log.d("NotificationReceiver", alarmUp? "true":"false" ); //always return false if (alarmUp) { //Log.d("NotificationReceiver", "Alarm is already active"); } else { //if no alarm, schedule one //Log.d("NotificationReceiver", "Alarm is not active"); this.scheduleAlarms(context); } } public static void scheduleAlarms(Context context) { //Log.d("NotificationReceiver", "scheduleAlarms"); Calendar alarmStartTime = Calendar.getInstance(); Calendar now = Calendar.getInstance(); alarmStartTime.set(Calendar.HOUR_OF_DAY, 13); alarmStartTime.set(Calendar.MINUTE, 31); alarmStartTime.set(Calendar.SECOND, 30); /*if (now.after(alarmStartTime)) { // not needed when using 1min repeat for testing Log.d("Alarm","Added a day"); alarmStartTime.add(Calendar.DATE, 1); }*/ Intent intent = new Intent(context, NotificationReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,alarmStartTime.getTimeInMillis(),60000 ,pendingIntent); // set to 1minute for testing purpose } public static void sendNotif(Context context){ //fire the notification //Log.d("NotificationReceiver", "sendNotif"); NotificationManager notificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); Intent intent1 = new Intent(context, Notification.class); intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity( context, 100, intent1, PendingIntent.FLAG_UPDATE_CURRENT); Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.ic_notif) .setContentTitle("Rappel MyCardioPad") .setContentText("Vous avez une séance d'éffort aujourd'hui") .setSound(soundUri) .setAutoCancel(true); notificationManager.notify(100, builder.build()); } public static void stopNotif(Context context){ //Allow to turn off the alarm/notification //Log.d("NotificationReceiver", "stopNotif"); Intent intent = new Intent(context, NotificationReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE); alarmManager.cancel(pendingIntent); pendingIntent.cancel(); } } 数据模型中插入新记录。

07-20 14:22:58.637 mycardiopad D/NotificationReceiver: scheduleAlarms
07-20 14:22:59.856 mycardiopad D/NotificationReceiver: onReceive
07-20 14:22:59.856 mycardiopad D/NotificationReceiver: sendNotif
07-20 14:22:59.863 mycardiopad D/NotificationReceiver: false
07-20 14:22:59.863 mycardiopad D/NotificationReceiver: Alarm is not active
07-20 14:22:59.863 mycardiopad D/NotificationReceiver: scheduleAlarms
07-20 14:22:59.908 mycardiopad D/NotificationReceiver: onReceive
07-20 14:22:59.908 mycardiopad D/NotificationReceiver: sendNotif
07-20 14:22:59.912 mycardiopad D/NotificationReceiver: false
07-20 14:22:59.912 mycardiopad D/NotificationReceiver: Alarm is not active
07-20 14:22:59.912 mycardiopad D/NotificationReceiver: scheduleAlarms
07-20 14:23:00.509 mycardiopad D/NotificationReceiver: onReceive
07-20 14:23:00.509 mycardiopad D/NotificationReceiver: sendNotif
07-20 14:23:00.520 mycardiopad D/NotificationReceiver: false
07-20 14:23:00.520 mycardiopad D/NotificationReceiver: Alarm is not active

但您想要将数据插入:ir.ui.view

<openerp>
<data>
    <record id="res_partner_field_ac" model="ir.ui.view">
        <field name="no_of_ac">10</field>
    </record>
</data>
</openerp>

注意:您遇到了问题,因为res.partner<openerp> <data> <record id="res_partner_field_ac" model="res.partner"> <field name="name">a name here because it's required when the field type != 'contact' </field> <field name="no_of_ac">10</field> </record> </data> </openerp> 模型中的必填字段。

答案 2 :(得分:1)

如果要添加数据记录,则应使用res.partner作为模型并定义必填字段:

<record id="res_partner_field_ac" model="res.partner">
    <field name="no_of_ac">10</field>
    <field name="name">NEW PARTNER NAME</field>
    <!-- define required fields -->
</record>

要定义视图,请查看Odoo views